Blender V5.0
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_math_color.h"
25#include "BLI_rand.h"
26
27#include "BLT_translation.hh"
28
29#include "BKE_asset.hh"
30#include "BKE_bpath.hh"
31#include "BKE_brush.hh"
32#include "BKE_colorband.hh"
33#include "BKE_colortools.hh"
34#include "BKE_grease_pencil.hh"
35#include "BKE_idprop.hh"
36#include "BKE_idtype.hh"
37#include "BKE_lib_id.hh"
38#include "BKE_lib_query.hh"
39#include "BKE_lib_remap.hh"
40#include "BKE_main.hh"
41#include "BKE_material.hh"
42#include "BKE_paint.hh"
43#include "BKE_paint_types.hh"
44#include "BKE_preview_image.hh"
45#include "BKE_texture.h"
46
48#include "IMB_imbuf.hh"
49#include "IMB_imbuf_types.hh"
50
51#include "RE_texture.h" /* RE_texture_evaluate */
52
53#include "BLO_read_write.hh"
54
55static void brush_init_data(ID *id)
56{
57 Brush *brush = reinterpret_cast<Brush *>(id);
59
61
62 /* enable fake user by default */
63 id_fake_user_set(&brush->id);
64
65 /* the default alpha falloff curve */
67
69
73
77}
78
79static void brush_copy_data(Main * /*bmain*/,
80 std::optional<Library *> /*owner_library*/,
81 ID *id_dst,
82 const ID *id_src,
83 const int flag)
84{
85 Brush *brush_dst = reinterpret_cast<Brush *>(id_dst);
86 const Brush *brush_src = reinterpret_cast<const Brush *>(id_src);
87
88 if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
89 BKE_previewimg_id_copy(&brush_dst->id, &brush_src->id);
90 }
91 else {
92 brush_dst->preview = nullptr;
93 }
94
97
101
102 brush_dst->curve_size = BKE_curvemapping_copy(brush_src->curve_size);
103 brush_dst->curve_strength = BKE_curvemapping_copy(brush_src->curve_strength);
104 brush_dst->curve_jitter = BKE_curvemapping_copy(brush_src->curve_jitter);
105
106 if (brush_src->gpencil_settings != nullptr) {
108 __func__, *(brush_src->gpencil_settings));
112 brush_src->gpencil_settings->curve_strength);
114 brush_src->gpencil_settings->curve_jitter);
115
121 brush_src->gpencil_settings->curve_rand_uv);
123 brush_src->gpencil_settings->curve_rand_hue);
128 }
129 if (brush_src->curves_sculpt_settings != nullptr) {
131 __func__, *(brush_src->curves_sculpt_settings));
134 }
135
136 /* enable fake user by default */
137 id_fake_user_set(&brush_dst->id);
138}
139
140static void brush_free_data(ID *id)
141{
142 Brush *brush = reinterpret_cast<Brush *>(id);
145
149
153
154 if (brush->gpencil_settings != nullptr) {
158
165
167 }
168 if (brush->curves_sculpt_settings != nullptr) {
171 }
172
173 MEM_SAFE_FREE(brush->gradient);
174
175 BKE_previewimg_free(&(brush->preview));
176}
177
178static void brush_make_local(Main *bmain, ID *id, const int flags)
179{
180 if (!ID_IS_LINKED(id)) {
181 return;
182 }
183
184 Brush *brush = reinterpret_cast<Brush *>(id);
185 const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
186
187 bool force_local, force_copy;
188 BKE_lib_id_make_local_generic_action_define(bmain, id, flags, &force_local, &force_copy);
189
190 if (force_local) {
191 BKE_lib_id_clear_library_data(bmain, &brush->id, flags);
192 BKE_lib_id_expand_local(bmain, &brush->id, flags);
193
194 /* enable fake user by default */
195 id_fake_user_set(&brush->id);
196 }
197 else if (force_copy) {
198 Brush *brush_new = reinterpret_cast<Brush *>(
199 BKE_id_copy(bmain, &brush->id)); /* Ensures FAKE_USER is set */
200
201 id_us_min(&brush_new->id);
202
203 BLI_assert(brush_new->id.flag & ID_FLAG_FAKEUSER);
204 BLI_assert(brush_new->id.us == 1);
205
206 /* Setting `newid` is mandatory for complex #make_lib_local logic. */
207 ID_NEW_SET(brush, brush_new);
208
209 if (!lib_local) {
210 BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
211 }
212 }
213}
214
228
230{
231 Brush *brush = reinterpret_cast<Brush *>(id);
232
233 fn.single(brush->color);
234 fn.single(brush->secondary_color);
235 if (brush->gradient) {
237 }
238
240}
241
242static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_address)
243{
244 Brush *brush = reinterpret_cast<Brush *>(id);
245
246 BLO_write_id_struct(writer, Brush, id_address, &brush->id);
247 BKE_id_blend_write(writer, &brush->id);
248
249 if (brush->curve_distance_falloff) {
251 }
252
253 if (brush->automasking_cavity_curve) {
255 }
256
257 if (brush->curve_rand_hue) {
259 }
260 if (brush->curve_rand_saturation) {
262 }
263 if (brush->curve_rand_value) {
265 }
266
267 if (brush->curve_size) {
269 }
270 if (brush->curve_strength) {
272 }
273 if (brush->curve_jitter) {
275 }
276
277 if (brush->gpencil_settings) {
279
282 }
283 if (brush->gpencil_settings->curve_strength) {
285 }
286 if (brush->gpencil_settings->curve_jitter) {
288 }
291 }
294 }
295 if (brush->gpencil_settings->curve_rand_uv) {
297 }
298 if (brush->gpencil_settings->curve_rand_hue) {
300 }
303 }
306 }
307 }
308 if (brush->curves_sculpt_settings) {
311 }
312 if (brush->gradient) {
313 BLO_write_struct(writer, ColorBand, brush->gradient);
314 }
315
316 BKE_previewimg_blend_write(writer, brush->preview);
317}
318
319static void brush_blend_read_data(BlendDataReader *reader, ID *id)
320{
321 Brush *brush = reinterpret_cast<Brush *>(id);
322
323 /* Falloff curve. */
325
326 BLO_read_struct(reader, ColorBand, &brush->gradient);
327
328 if (brush->curve_distance_falloff) {
330 }
331 else {
333 }
334
336 if (brush->automasking_cavity_curve) {
338 }
339 else {
341 }
342
344 if (brush->curve_rand_hue) {
346 }
347 else {
349 }
350
352 if (brush->curve_rand_saturation) {
354 }
355 else {
357 }
358
360 if (brush->curve_rand_value) {
362 }
363 else {
365 }
366
367 BLO_read_struct(reader, CurveMapping, &brush->curve_size);
368 if (brush->curve_size) {
370 }
371 else {
373 }
374
376 if (brush->curve_strength) {
378 }
379 else {
381 }
382
383 BLO_read_struct(reader, CurveMapping, &brush->curve_jitter);
384 if (brush->curve_jitter) {
386 }
387 else {
389 }
390
391 /* grease pencil */
393 if (brush->gpencil_settings != nullptr) {
397
404
407 }
408
409 if (brush->gpencil_settings->curve_strength) {
411 }
412
413 if (brush->gpencil_settings->curve_jitter) {
415 }
416
419 }
420
423 }
424
425 if (brush->gpencil_settings->curve_rand_uv) {
427 }
428
429 if (brush->gpencil_settings->curve_rand_hue) {
431 }
432
435 }
436
439 }
440 }
441
443 if (brush->curves_sculpt_settings) {
447 }
448 }
449
450 BLO_read_struct(reader, PreviewImage, &brush->preview);
451 BKE_previewimg_blend_read(reader, brush->preview);
452
453 brush->has_unsaved_changes = false;
454}
455
457{
458 Brush *brush = reinterpret_cast<Brush *>(id);
459
460 /* Update brush settings depending on availability of other IDs. */
461 if (brush->gpencil_settings != nullptr) {
463 if (!brush->gpencil_settings->material) {
465 }
466 }
467 else {
468 brush->gpencil_settings->material = nullptr;
469 }
470 }
471}
472
473static void brush_asset_metadata_ensure(void *asset_ptr, AssetMetaData *asset_data)
474{
475 using namespace blender;
476 using namespace blender::bke;
477
478 Brush *brush = reinterpret_cast<Brush *>(asset_ptr);
479 BLI_assert(GS(brush->id.name) == ID_BR);
480
481 /* Most names copied from brush RNA (not all are available there though). */
482 constexpr std::array mode_map{
483 std::tuple{"use_paint_sculpt", OB_MODE_SCULPT, "sculpt_brush_type"},
484 std::tuple{"use_paint_vertex", OB_MODE_VERTEX_PAINT, "vertex_brush_type"},
485 std::tuple{"use_paint_weight", OB_MODE_WEIGHT_PAINT, "weight_brush_type"},
486 std::tuple{"use_paint_image", OB_MODE_TEXTURE_PAINT, "image_brush_type"},
487 /* Sculpt UVs in the image editor while in edit mode. */
488 std::tuple{"use_paint_uv_sculpt", OB_MODE_EDIT, "image_brush_type"},
489 std::tuple{"use_paint_grease_pencil", OB_MODE_PAINT_GREASE_PENCIL, "gpencil_brush_type"},
490 /* Note: Not defined in brush RNA, own name. */
491 std::tuple{
492 "use_sculpt_grease_pencil", OB_MODE_SCULPT_GREASE_PENCIL, "gpencil_sculpt_brush_type"},
493 std::tuple{
494 "use_vertex_grease_pencil", OB_MODE_VERTEX_GREASE_PENCIL, "gpencil_vertex_brush_type"},
495 std::tuple{"use_weight_gpencil", OB_MODE_WEIGHT_GREASE_PENCIL, "gpencil_weight_brush_type"},
496 std::tuple{"use_paint_sculpt_curves", OB_MODE_SCULPT_CURVES, "curves_sculpt_brush_type"},
497 };
498
499 for (const auto &[prop_name, mode, tool_prop_name] : mode_map) {
500 /* Only add booleans for supported modes. */
501 if (!(brush->ob_mode & mode)) {
502 continue;
503 }
504 auto mode_property = idprop::create_bool(prop_name, true);
505 BKE_asset_metadata_idprop_ensure(asset_data, mode_property.release());
506
507 if (std::optional<int> brush_tool = BKE_paint_get_brush_type_from_obmode(brush, mode)) {
508 auto type_property = idprop::create(tool_prop_name, *brush_tool);
509 BKE_asset_metadata_idprop_ensure(asset_data, type_property.release());
510 }
511 else {
513 }
514 }
515}
516
518 /*pre_save_fn*/ brush_asset_metadata_ensure,
519 /*on_mark_asset_fn*/ brush_asset_metadata_ensure,
520};
521
523 /*id_code*/ Brush::id_type,
524 /*id_filter*/ FILTER_ID_BR,
525 /*dependencies_id_types*/
527 /*main_listbase_index*/ INDEX_ID_BR,
528 /*struct_size*/ sizeof(Brush),
529 /*name*/ "Brush",
530 /*name_plural*/ N_("brushes"),
531 /*translation_context*/ BLT_I18NCONTEXT_ID_BRUSH,
533 /*asset_type_info*/ &AssetType_BR,
534
535 /*init_data*/ brush_init_data,
536 /*copy_data*/ brush_copy_data,
537 /*free_data*/ brush_free_data,
538 /*make_local*/ brush_make_local,
539 /*foreach_id*/ brush_foreach_id,
540 /*foreach_cache*/ nullptr,
541 /*foreach_path*/ nullptr,
542 /*foreach_working_space_color*/ brush_foreach_working_space_color,
543 /*owner_pointer_get*/ nullptr,
544
545 /*blend_write*/ brush_blend_write,
546 /*blend_read_data*/ brush_blend_read_data,
547 /*blend_read_after_liblink*/ brush_blend_read_after_liblink,
548
549 /*blend_read_undo_preserve*/ nullptr,
550
551 /*lib_override_apply_post*/ nullptr,
552};
553
555
557{
559 BLI_rng_srandom(brush_rng, 31415682);
560}
561
563{
564 if (brush_rng == nullptr) {
565 return;
566 }
568 brush_rng = nullptr;
569}
570
572{
573
574 const Brush *brush_def = DNA_struct_default_get(Brush);
575
576#define FROM_DEFAULT(member) \
577 memcpy((void *)&brush->member, (void *)&brush_def->member, sizeof(brush->member))
578#define FROM_DEFAULT_PTR(member) memcpy(brush->member, brush_def->member, sizeof(brush->member))
579
582 FROM_DEFAULT(weight);
584 FROM_DEFAULT(alpha);
585 FROM_DEFAULT(hardness);
586 FROM_DEFAULT(autosmooth_factor);
587 FROM_DEFAULT(topology_rake_factor);
588 FROM_DEFAULT(crease_pinch_factor);
589 FROM_DEFAULT(normal_radius_factor);
590 FROM_DEFAULT(wet_paint_radius_factor);
591 FROM_DEFAULT(area_radius_factor);
592 FROM_DEFAULT(disconnected_distance_max);
593 FROM_DEFAULT(sculpt_plane);
594 FROM_DEFAULT(plane_offset);
595 FROM_DEFAULT(normal_weight);
596 FROM_DEFAULT(fill_threshold);
598 FROM_DEFAULT(sampling_flag);
600 FROM_DEFAULT_PTR(secondary_color);
601 FROM_DEFAULT(spacing);
602 FROM_DEFAULT(smooth_stroke_radius);
603 FROM_DEFAULT(smooth_stroke_factor);
604 FROM_DEFAULT(rate);
605 FROM_DEFAULT(jitter);
606 FROM_DEFAULT(texture_sample_bias);
607 FROM_DEFAULT(texture_overlay_alpha);
608 FROM_DEFAULT(mask_overlay_alpha);
609 FROM_DEFAULT(cursor_overlay_alpha);
611 FROM_DEFAULT_PTR(add_col);
612 FROM_DEFAULT_PTR(sub_col);
613 FROM_DEFAULT(stencil_pos);
614 FROM_DEFAULT(stencil_dimension);
615 FROM_DEFAULT(mtex);
616 FROM_DEFAULT(mask_mtex);
617 FROM_DEFAULT(falloff_shape);
618 FROM_DEFAULT(tip_scale_x);
619 FROM_DEFAULT(tip_roundness);
620
621#undef FROM_DEFAULT
622#undef FROM_DEFAULT_PTR
623}
624
625/* Datablock add/copy/free/make_local */
626
627Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode)
628{
630
631 brush->ob_mode = ob_mode;
632
633 if (ob_mode == OB_MODE_SCULPT_CURVES) {
635 }
636 else if (ELEM(ob_mode,
641 {
643 }
644
645 return brush;
646}
647
649{
650 if (brush->gpencil_settings == nullptr) {
651 brush->gpencil_settings = MEM_callocN<BrushGpencilSettings>("BrushGpencilSettings");
652 }
653
654 brush->gpencil_settings->draw_smoothlvl = 1;
655 brush->gpencil_settings->flag = 0;
656 brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
657 brush->gpencil_settings->draw_strength = 1.0f;
658 brush->gpencil_settings->draw_jitter = 0.0f;
659 brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
660
661 /* curves */
662 brush->gpencil_settings->curve_sensitivity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
663 brush->gpencil_settings->curve_strength = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
664 brush->gpencil_settings->curve_jitter = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
665
666 brush->gpencil_settings->curve_rand_pressure = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
667 brush->gpencil_settings->curve_rand_strength = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
668 brush->gpencil_settings->curve_rand_uv = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
669 brush->gpencil_settings->curve_rand_hue = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
670 brush->gpencil_settings->curve_rand_saturation = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
671 brush->gpencil_settings->curve_rand_value = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
672}
673
675{
676 if (brush->id.tag & ID_TAG_INDIRECT) {
677 return false;
678 }
679 if (ID_REAL_USERS(brush) <= 1 && ID_EXTRA_USERS(brush) == 0 &&
681 {
682 return false;
683 }
684
685 BKE_id_delete(bmain, brush);
686
687 return true;
688}
689
691 Brush *brush,
692 eDupli_ID_Flags /*dupflag*/,
693 /*eLibIDDuplicateFlags*/ uint duplicate_options)
694{
695 const bool is_subprocess = (duplicate_options & LIB_ID_DUPLICATE_IS_SUBPROCESS) != 0;
696 const bool is_root_id = (duplicate_options & LIB_ID_DUPLICATE_IS_ROOT_ID) != 0;
697
699
700 if (!is_subprocess) {
702 }
703 if (is_root_id) {
704 duplicate_options &= ~LIB_ID_DUPLICATE_IS_ROOT_ID;
705 }
706
707 constexpr int id_copy_flag = LIB_ID_COPY_DEFAULT;
708
709 Brush *new_brush = reinterpret_cast<Brush *>(
710 BKE_id_copy_for_duplicate(bmain, &brush->id, dupflag, id_copy_flag));
711
712 /* Currently this duplicates everything and the passed in value of `dupflag` is ignored. Ideally,
713 * this should both check user preferences and do further filtering based on eDupli_ID_Flags. */
714 auto dependencies_cb = [&](const LibraryIDLinkCallbackData *cb_data) -> int {
715 if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_EMBEDDED_NOT_OWNING)) {
716 return IDWALK_NOP;
717 }
718 if (cb_data->cb_flag & IDWALK_CB_LOOPBACK) {
719 return IDWALK_NOP;
720 }
721
722 BKE_id_copy_for_duplicate(bmain, *cb_data->id_pointer, dupflag, id_copy_flag);
723 return IDWALK_NOP;
724 };
725
726 BKE_library_foreach_ID_link(bmain, &new_brush->id, dependencies_cb, nullptr, IDWALK_RECURSE);
727
728 if (!is_subprocess) {
729 /* This code will follow into all ID links using an ID tagged with ID_TAG_NEW. */
731
732#ifndef NDEBUG
733 /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those flags. */
734 ID *id_iter;
735 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
736 BLI_assert((id_iter->tag & ID_TAG_NEW) == 0);
737 }
739#endif
740
741 /* Cleanup. */
743 }
744
745 return new_brush;
746}
747
749{
750 if (brush->curves_sculpt_settings == nullptr) {
751 brush->curves_sculpt_settings = MEM_callocN<BrushCurvesSculptSettings>(__func__);
752 }
753 BrushCurvesSculptSettings *settings = brush->curves_sculpt_settings;
755 settings->add_amount = 1;
756 settings->points_per_curve = 8;
757 settings->minimum_length = 0.01f;
758 settings->curve_length = 0.3f;
759 settings->curve_radius = 0.01f;
760 settings->density_add_attempts = 100;
761 settings->curve_parameter_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
762}
763
765{
766 if (brush && ID_IS_LINKED(brush)) {
767 brush->has_unsaved_changes = true;
768 }
769}
770
772{
773 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
774 if (brush->ob_mode & ob_mode) {
775 return brush;
776 }
777 }
778 return nullptr;
779}
780
782{
783 /* create a fake brush and set it to the defaults */
784 Brush def = blender::dna::shallow_zero_initialize();
785 brush_defaults(&def);
786
787#define BR_TEST(field, t) \
788 if (br->field != def.field) { \
789 printf("br->" #field " = %" #t ";\n", br->field); \
790 } \
791 ((void)0)
792
793#define BR_TEST_FLAG(_f) \
794 if ((br->flag & _f) && !(def.flag & _f)) { \
795 printf("br->flag |= " #_f ";\n"); \
796 } \
797 else if (!(br->flag & _f) && (def.flag & _f)) { \
798 printf("br->flag &= ~" #_f ";\n"); \
799 } \
800 ((void)0)
801
802#define BR_TEST_FLAG_OVERLAY(_f) \
803 if ((br->overlay_flags & _f) && !(def.overlay_flags & _f)) { \
804 printf("br->overlay_flags |= " #_f ";\n"); \
805 } \
806 else if (!(br->overlay_flags & _f) && (def.overlay_flags & _f)) { \
807 printf("br->overlay_flags &= ~" #_f ";\n"); \
808 } \
809 ((void)0)
810
811 /* print out any non-default brush state */
812 BR_TEST(normal_weight, f);
813
814 BR_TEST(blend, d);
815 BR_TEST(size, d);
816
817 /* br->flag */
840
847
848 BR_TEST(jitter, f);
849 BR_TEST(spacing, d);
850 BR_TEST(smooth_stroke_radius, d);
851 BR_TEST(smooth_stroke_factor, f);
852 BR_TEST(rate, f);
853
854 BR_TEST(alpha, f);
855
856 BR_TEST(sculpt_plane, d);
857
858 BR_TEST(plane_offset, f);
859
860 BR_TEST(autosmooth_factor, f);
861
862 BR_TEST(topology_rake_factor, f);
863
864 BR_TEST(crease_pinch_factor, f);
865
866 BR_TEST(plane_trim, f);
867
868 BR_TEST(texture_sample_bias, f);
869 BR_TEST(texture_overlay_alpha, d);
870
871 BR_TEST(add_col[0], f);
872 BR_TEST(add_col[1], f);
873 BR_TEST(add_col[2], f);
874 BR_TEST(add_col[3], f);
875 BR_TEST(sub_col[0], f);
876 BR_TEST(sub_col[1], f);
877 BR_TEST(sub_col[2], f);
878 BR_TEST(sub_col[3], f);
879
880 printf("\n");
881
882#undef BR_TEST
883#undef BR_TEST_FLAG
884}
885
887{
888 CurveMapping *cumap = nullptr;
889 CurveMap *cuma = nullptr;
890
891 if (!b->curve_distance_falloff) {
892 b->curve_distance_falloff = BKE_curvemapping_add(1, 0, 0, 1, 1);
893 }
894 cumap = b->curve_distance_falloff;
896 cumap->preset = preset;
897
898 cuma = b->curve_distance_falloff->cm;
900 BKE_curvemapping_changed(cumap, false);
902}
903
904const MTex *BKE_brush_mask_texture_get(const Brush *brush, const eObjectMode object_mode)
905{
906 if (object_mode == OB_MODE_SCULPT) {
907 return &brush->mtex;
908 }
909 return &brush->mask_mtex;
910}
911
912const MTex *BKE_brush_color_texture_get(const Brush *brush, const eObjectMode object_mode)
913{
914 if (object_mode == OB_MODE_SCULPT) {
915 return &brush->mask_mtex;
916 }
917 return &brush->mtex;
918}
919
921 const Brush *br,
922 const MTex *mtex,
923 const float point[3],
924 float rgba[4],
925 const int thread,
926 ImagePool *pool)
927{
928 const blender::bke::PaintRuntime *paint_runtime = paint->runtime;
929 float intensity = 1.0;
930 bool hasrgb = false;
931
932 if (mtex == nullptr || mtex->tex == nullptr) {
933 intensity = 1;
934 }
935 else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
936 /* Get strength by feeding the vertex
937 * location directly into a texture */
938 hasrgb = RE_texture_evaluate(mtex, point, thread, pool, false, false, &intensity, rgba);
939 }
940 else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
941 float rotation = -mtex->rot;
942 const float point_2d[2] = {point[0], point[1]};
943 float x, y;
944 float co[3];
945
946 x = point_2d[0] - br->stencil_pos[0];
947 y = point_2d[1] - br->stencil_pos[1];
948
949 if (rotation > 0.001f || rotation < -0.001f) {
950 const float angle = atan2f(y, x) + rotation;
951 const float flen = sqrtf(x * x + y * y);
952
953 x = flen * cosf(angle);
954 y = flen * sinf(angle);
955 }
956
957 if (fabsf(x) > br->stencil_dimension[0] || fabsf(y) > br->stencil_dimension[1]) {
958 zero_v4(rgba);
959 return 0.0f;
960 }
961 x /= (br->stencil_dimension[0]);
962 y /= (br->stencil_dimension[1]);
963
964 co[0] = x;
965 co[1] = y;
966 co[2] = 0.0f;
967
968 hasrgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
969 }
970 else {
971 float rotation = -mtex->rot;
972 const float point_2d[2] = {point[0], point[1]};
973 float x = 0.0f, y = 0.0f; /* Quite warnings */
974 float invradius = 1.0f; /* Quite warnings */
975 float co[3];
976
977 if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
978 /* keep coordinates relative to mouse */
979
980 rotation -= paint_runtime->brush_rotation;
981
982 x = point_2d[0] - paint_runtime->tex_mouse[0];
983 y = point_2d[1] - paint_runtime->tex_mouse[1];
984
985 /* use pressure adjusted size for fixed mode */
986 invradius = 1.0f / paint_runtime->pixel_radius;
987 }
988 else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
989 /* leave the coordinates relative to the screen */
990
991 /* use unadjusted size for tiled mode */
992 invradius = 1.0f / paint_runtime->start_pixel_radius;
993
994 x = point_2d[0];
995 y = point_2d[1];
996 }
997 else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
998 rotation -= paint_runtime->brush_rotation;
999 /* these contain a random coordinate */
1000 x = point_2d[0] - paint_runtime->tex_mouse[0];
1001 y = point_2d[1] - paint_runtime->tex_mouse[1];
1002
1003 invradius = 1.0f / paint_runtime->pixel_radius;
1004 }
1005
1006 x *= invradius;
1007 y *= invradius;
1008
1009 /* it is probably worth optimizing for those cases where
1010 * the texture is not rotated by skipping the calls to
1011 * atan2, sqrtf, sin, and cos. */
1012 if (rotation > 0.001f || rotation < -0.001f) {
1013 const float angle = atan2f(y, x) + rotation;
1014 const float flen = sqrtf(x * x + y * y);
1015
1016 x = flen * cosf(angle);
1017 y = flen * sinf(angle);
1018 }
1019
1020 co[0] = x;
1021 co[1] = y;
1022 co[2] = 0.0f;
1023
1024 hasrgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
1025 }
1026
1027 intensity += br->texture_sample_bias;
1028
1029 if (!hasrgb) {
1030 rgba[0] = intensity;
1031 rgba[1] = intensity;
1032 rgba[2] = intensity;
1033 rgba[3] = 1.0f;
1034 }
1035 /* For consistency, sampling always returns color in linear space */
1036 else if (paint_runtime->do_linear_conversion) {
1038 }
1039
1040 return intensity;
1041}
1042
1044 const Paint *paint, Brush *br, const float point[2], const int thread, ImagePool *pool)
1045{
1046 const blender::bke::PaintRuntime *paint_runtime = paint->runtime;
1047 MTex *mtex = &br->mask_mtex;
1048 float rgba[4], intensity;
1049
1050 if (!mtex->tex) {
1051 return 1.0f;
1052 }
1054 float rotation = -mtex->rot;
1055 const float point_2d[2] = {point[0], point[1]};
1056 float x, y;
1057 float co[3];
1058
1059 x = point_2d[0] - br->mask_stencil_pos[0];
1060 y = point_2d[1] - br->mask_stencil_pos[1];
1061
1062 if (rotation > 0.001f || rotation < -0.001f) {
1063 const float angle = atan2f(y, x) + rotation;
1064 const float flen = sqrtf(x * x + y * y);
1065
1066 x = flen * cosf(angle);
1067 y = flen * sinf(angle);
1068 }
1069
1070 if (fabsf(x) > br->mask_stencil_dimension[0] || fabsf(y) > br->mask_stencil_dimension[1]) {
1071 zero_v4(rgba);
1072 return 0.0f;
1073 }
1074 x /= (br->mask_stencil_dimension[0]);
1075 y /= (br->mask_stencil_dimension[1]);
1076
1077 co[0] = x;
1078 co[1] = y;
1079 co[2] = 0.0f;
1080
1081 RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
1082 }
1083 else {
1084 float rotation = -mtex->rot;
1085 const float point_2d[2] = {point[0], point[1]};
1086 float x = 0.0f, y = 0.0f; /* Quite warnings */
1087 float invradius = 1.0f; /* Quite warnings */
1088 float co[3];
1089
1090 if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
1091 /* keep coordinates relative to mouse */
1092
1093 rotation -= paint_runtime->brush_rotation_sec;
1094
1095 x = point_2d[0] - paint_runtime->mask_tex_mouse[0];
1096 y = point_2d[1] - paint_runtime->mask_tex_mouse[1];
1097
1098 /* use pressure adjusted size for fixed mode */
1099 invradius = 1.0f / paint_runtime->pixel_radius;
1100 }
1101 else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
1102 /* leave the coordinates relative to the screen */
1103
1104 /* use unadjusted size for tiled mode */
1105 invradius = 1.0f / paint_runtime->start_pixel_radius;
1106
1107 x = point_2d[0];
1108 y = point_2d[1];
1109 }
1110 else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
1111 rotation -= paint_runtime->brush_rotation_sec;
1112 /* these contain a random coordinate */
1113 x = point_2d[0] - paint_runtime->mask_tex_mouse[0];
1114 y = point_2d[1] - paint_runtime->mask_tex_mouse[1];
1115
1116 invradius = 1.0f / paint_runtime->pixel_radius;
1117 }
1118
1119 x *= invradius;
1120 y *= invradius;
1121
1122 /* it is probably worth optimizing for those cases where
1123 * the texture is not rotated by skipping the calls to
1124 * atan2, sqrtf, sin, and cos. */
1125 if (rotation > 0.001f || rotation < -0.001f) {
1126 const float angle = atan2f(y, x) + rotation;
1127 const float flen = sqrtf(x * x + y * y);
1128
1129 x = flen * cosf(angle);
1130 y = flen * sinf(angle);
1131 }
1132
1133 co[0] = x;
1134 co[1] = y;
1135 co[2] = 0.0f;
1136
1137 RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
1138 }
1139
1140 CLAMP(intensity, 0.0f, 1.0f);
1141
1142 switch (br->mask_pressure) {
1144 intensity = ((1.0f - intensity) < paint_runtime->size_pressure_value) ? 1.0f : 0.0f;
1145 break;
1147 intensity = paint_runtime->size_pressure_value +
1148 intensity * (1.0f - paint_runtime->size_pressure_value);
1149 break;
1150 default:
1151 break;
1152 }
1153
1154 return intensity;
1155}
1156
1157/* -------------------------------------------------------------------- */
1160
1161const float *BKE_brush_color_get(const Paint *paint, const Brush *brush)
1162{
1164 return paint->unified_paint_settings.color;
1165 }
1166 return brush->color;
1167}
1168
1170std::optional<BrushColorJitterSettings> BKE_brush_color_jitter_get_settings(const Paint *paint,
1171 const Brush *brush)
1172{
1174 if ((paint->unified_paint_settings.flag & UNIFIED_PAINT_COLOR_JITTER) == 0) {
1175 return std::nullopt;
1176 }
1177
1178 const UnifiedPaintSettings &settings = paint->unified_paint_settings;
1180 settings.color_jitter_flag,
1181 settings.hsv_jitter[0],
1182 settings.hsv_jitter[1],
1183 settings.hsv_jitter[2],
1184 settings.curve_rand_hue,
1185 settings.curve_rand_saturation,
1186 settings.curve_rand_value,
1187 };
1188 }
1189
1190 if ((brush->flag2 & BRUSH_JITTER_COLOR) == 0) {
1191 return std::nullopt;
1192 }
1193
1195 brush->color_jitter_flag,
1196 brush->hsv_jitter[0],
1197 brush->hsv_jitter[1],
1198 brush->hsv_jitter[2],
1199 brush->curve_rand_hue,
1200 brush->curve_rand_saturation,
1201 brush->curve_rand_value,
1202 };
1203}
1204
1206{
1208 return paint->unified_paint_settings.secondary_color;
1209 }
1210 return brush->secondary_color;
1211}
1212
1214{
1216 UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1217 copy_v3_v3(ups->color, color);
1219 }
1220 else {
1221 copy_v3_v3(brush->color, color);
1224 }
1225}
1226
1228{
1229 /* For forward compatibility. */
1230 linearrgb_to_srgb_v3_v3(brush->rgb, brush->color);
1231 linearrgb_to_srgb_v3_v3(brush->secondary_rgb, brush->secondary_color);
1232}
1233
1235{
1236 /* For forward compatibility. */
1237 linearrgb_to_srgb_v3_v3(ups->rgb, ups->color);
1238 linearrgb_to_srgb_v3_v3(ups->secondary_rgb, ups->secondary_color);
1239}
1240
1241/* Be careful about setting size and unprojected size because they depend on one another these
1242 * functions do not set the other corresponding value this can lead to odd behavior if size and
1243 * unprojected radius become inconsistent. The biggest problem is that it isn't possible to change
1244 * unprojected radius because a view context is not available. My usual solution to this is to use
1245 * the ratio of change of the size to change the unprojected radius. Not completely convinced that
1246 * is correct. In any case, a better solution is needed to prevent inconsistency. */
1247
1249{
1250 UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1251
1252 /* make sure range is sane */
1254
1255 if (ups->flag & UNIFIED_PAINT_SIZE) {
1256 ups->size = size;
1257 }
1258 else {
1259 brush->size = size;
1261 }
1262}
1263
1265{
1266 const UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1267 int size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
1268
1269 return size;
1270}
1271
1273{
1274 return BKE_brush_size_get(paint, brush) / 2.0f;
1275}
1276
1278{
1279 const short us_flag = paint->unified_paint_settings.flag;
1280
1281 return (us_flag & UNIFIED_PAINT_SIZE) ? (us_flag & UNIFIED_PAINT_BRUSH_LOCK_SIZE) :
1282 (brush->flag & BRUSH_LOCK_SIZE);
1283}
1284
1286{
1287 return brush->flag & BRUSH_SIZE_PRESSURE;
1288}
1289
1291{
1292 return brush->flag & BRUSH_ALPHA_PRESSURE;
1293}
1294
1295void BKE_brush_unprojected_size_set(Paint *paint, Brush *brush, float unprojected_size)
1296{
1297 UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1298
1299 if (ups->flag & UNIFIED_PAINT_SIZE) {
1300 ups->unprojected_size = unprojected_size;
1301 }
1302 else {
1303 brush->unprojected_size = unprojected_size;
1305 }
1306}
1307
1309{
1310 const UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1311
1312 return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->unprojected_size : brush->unprojected_size;
1313}
1314
1319
1320void BKE_brush_scale_unprojected_size(float *unprojected_size,
1321 int new_brush_size,
1322 int old_brush_size)
1323{
1324 float scale = new_brush_size;
1325 /* avoid division by zero */
1326 if (old_brush_size != 0) {
1327 scale /= float(old_brush_size);
1328 }
1329 (*unprojected_size) *= scale;
1330}
1331
1332void BKE_brush_scale_size(int *r_brush_size,
1333 float new_unprojected_size,
1334 float old_unprojected_size)
1335{
1336 float scale = new_unprojected_size;
1337 /* avoid division by zero */
1338 if (old_unprojected_size != 0) {
1339 scale /= new_unprojected_size;
1340 }
1341 (*r_brush_size) = int(float(*r_brush_size) * scale);
1342}
1343
1345{
1346 UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1347
1348 if (ups->flag & UNIFIED_PAINT_ALPHA) {
1349 ups->alpha = alpha;
1350 }
1351 else {
1352 brush->alpha = alpha;
1354 }
1355}
1356
1358{
1359 const UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1360
1361 return (ups->flag & UNIFIED_PAINT_ALPHA) ? ups->alpha : brush->alpha;
1362}
1363
1365{
1366 const UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1367
1368 return (ups->flag & UNIFIED_PAINT_WEIGHT) ? ups->weight : brush->weight;
1369}
1370
1372{
1373 UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1374
1375 if (ups->flag & UNIFIED_PAINT_WEIGHT) {
1376 ups->weight = value;
1377 }
1378 else {
1379 brush->weight = value;
1381 }
1382}
1383
1385{
1386 const UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1387
1388 return (ups->flag & UNIFIED_PAINT_INPUT_SAMPLES) ? ups->input_samples : brush->input_samples;
1389}
1390
1392{
1393 UnifiedPaintSettings *ups = &paint->unified_paint_settings;
1394
1395 if (ups->flag & UNIFIED_PAINT_INPUT_SAMPLES) {
1396 ups->input_samples = value;
1397 }
1398 else {
1399 brush->input_samples = value;
1401 }
1402}
1403
1405
1407 const Brush &brush,
1408 const float pos[2],
1409 float jitterpos[2])
1410{
1411 float rand_pos[2];
1412 float spread;
1413 int diameter;
1414
1415 do {
1416 rand_pos[0] = BLI_rng_get_float(brush_rng) - 0.5f;
1417 rand_pos[1] = BLI_rng_get_float(brush_rng) - 0.5f;
1418 } while (len_squared_v2(rand_pos) > square_f(0.5f));
1419
1420 if (brush.flag & BRUSH_ABSOLUTE_JITTER) {
1421 diameter = 2 * brush.jitter_absolute;
1422 spread = 1.0;
1423 }
1424 else {
1425 diameter = 2 * BKE_brush_radius_get(&paint, &brush);
1426 spread = brush.jitter;
1427 }
1428 /* find random position within a circle of diameter 1 */
1429 jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * spread;
1430 jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * spread;
1431}
1432
1434{
1435 blender::bke::PaintRuntime &paint_runtime = *paint->runtime;
1436 /* we multiply with brush radius as an optimization for the brush
1437 * texture sampling functions */
1438 if (mask) {
1439 paint_runtime.mask_tex_mouse[0] = BLI_rng_get_float(brush_rng) * paint_runtime.pixel_radius;
1440 paint_runtime.mask_tex_mouse[1] = BLI_rng_get_float(brush_rng) * paint_runtime.pixel_radius;
1441 }
1442 else {
1443 paint_runtime.tex_mouse[0] = BLI_rng_get_float(brush_rng) * paint_runtime.pixel_radius;
1444 paint_runtime.tex_mouse[1] = BLI_rng_get_float(brush_rng) * paint_runtime.pixel_radius;
1445 }
1446}
1447
1449 const CurveMapping *cumap,
1450 const blender::Span<float> distances,
1451 const float brush_radius,
1452 const blender::MutableSpan<float> factors)
1453{
1454 BLI_assert(factors.size() == distances.size());
1455
1456 const float radius_rcp = blender::math::rcp(brush_radius);
1457 switch (preset) {
1458 case BRUSH_CURVE_CUSTOM: {
1459 for (const int i : distances.index_range()) {
1460 const float distance = distances[i];
1461 if (distance >= brush_radius) {
1462 factors[i] = 0.0f;
1463 continue;
1464 }
1465 factors[i] *= BKE_curvemapping_evaluateF(cumap, 0, distance * radius_rcp);
1466 }
1467 break;
1468 }
1469 case BRUSH_CURVE_SHARP: {
1470 for (const int i : distances.index_range()) {
1471 const float distance = distances[i];
1472 if (distance >= brush_radius) {
1473 factors[i] = 0.0f;
1474 continue;
1475 }
1476 const float factor = 1.0f - distance * radius_rcp;
1477 factors[i] *= factor * factor;
1478 }
1479 break;
1480 }
1481 case BRUSH_CURVE_SMOOTH: {
1482 for (const int i : distances.index_range()) {
1483 const float distance = distances[i];
1484 if (distance >= brush_radius) {
1485 factors[i] = 0.0f;
1486 continue;
1487 }
1488 const float factor = 1.0f - distance * radius_rcp;
1489 factors[i] *= 3.0f * factor * factor - 2.0f * factor * factor * factor;
1490 }
1491 break;
1492 }
1493 case BRUSH_CURVE_SMOOTHER: {
1494 for (const int i : distances.index_range()) {
1495 const float distance = distances[i];
1496 if (distance >= brush_radius) {
1497 factors[i] = 0.0f;
1498 continue;
1499 }
1500 const float factor = 1.0f - distance * radius_rcp;
1501 factors[i] *= pow3f(factor) * (factor * (factor * 6.0f - 15.0f) + 10.0f);
1502 }
1503 break;
1504 }
1505 case BRUSH_CURVE_ROOT: {
1506 for (const int i : distances.index_range()) {
1507 const float distance = distances[i];
1508 if (distance >= brush_radius) {
1509 factors[i] = 0.0f;
1510 continue;
1511 }
1512 const float factor = 1.0f - distance * radius_rcp;
1513 factors[i] *= sqrtf(factor);
1514 }
1515 break;
1516 }
1517 case BRUSH_CURVE_LIN: {
1518 for (const int i : distances.index_range()) {
1519 const float distance = distances[i];
1520 if (distance >= brush_radius) {
1521 factors[i] = 0.0f;
1522 continue;
1523 }
1524 const float factor = 1.0f - distance * radius_rcp;
1525 factors[i] *= factor;
1526 }
1527 break;
1528 }
1529 case BRUSH_CURVE_CONSTANT: {
1530 for (const int i : distances.index_range()) {
1531 const float distance = distances[i];
1532 if (distance >= brush_radius) {
1533 factors[i] = 0.0f;
1534 }
1535 }
1536 break;
1537 }
1538 case BRUSH_CURVE_SPHERE: {
1539 for (const int i : distances.index_range()) {
1540 const float distance = distances[i];
1541 if (distance >= brush_radius) {
1542 factors[i] = 0.0f;
1543 continue;
1544 }
1545 const float factor = 1.0f - distance * radius_rcp;
1546 factors[i] *= sqrtf(2 * factor - factor * factor);
1547 }
1548 break;
1549 }
1550 case BRUSH_CURVE_POW4: {
1551 for (const int i : distances.index_range()) {
1552 const float distance = distances[i];
1553 if (distance >= brush_radius) {
1554 factors[i] = 0.0f;
1555 continue;
1556 }
1557 const float factor = 1.0f - distance * radius_rcp;
1558 factors[i] *= factor * factor * factor * factor;
1559 }
1560 break;
1561 }
1562 case BRUSH_CURVE_INVSQUARE: {
1563 for (const int i : distances.index_range()) {
1564 const float distance = distances[i];
1565 if (distance >= brush_radius) {
1566 factors[i] = 0.0f;
1567 continue;
1568 }
1569 const float factor = 1.0f - distance * radius_rcp;
1570 factors[i] *= factor * (2.0f - factor);
1571 }
1572 break;
1573 }
1574 }
1575}
1576
1578 const CurveMapping *cumap,
1579 const float distance,
1580 const float brush_radius)
1581{
1582 BLI_assert(distance >= 0.0f);
1583 BLI_assert(brush_radius >= 0.0f);
1584
1585 float p = distance;
1586 float strength = 1.0f;
1587
1588 if (p >= brush_radius) {
1589 return 0;
1590 }
1591
1592 p = p / brush_radius;
1593 p = 1.0f - p;
1594
1595 switch (preset) {
1596 case BRUSH_CURVE_CUSTOM:
1597 strength = BKE_curvemapping_evaluateF(cumap, 0, 1.0f - p);
1598 break;
1599 case BRUSH_CURVE_SHARP:
1600 strength = p * p;
1601 break;
1602 case BRUSH_CURVE_SMOOTH:
1603 strength = 3.0f * p * p - 2.0f * p * p * p;
1604 break;
1606 strength = pow3f(p) * (p * (p * 6.0f - 15.0f) + 10.0f);
1607 break;
1608 case BRUSH_CURVE_ROOT:
1609 strength = sqrtf(p);
1610 break;
1611 case BRUSH_CURVE_LIN:
1612 strength = p;
1613 break;
1615 strength = 1.0f;
1616 break;
1617 case BRUSH_CURVE_SPHERE:
1618 strength = sqrtf(2 * p - p * p);
1619 break;
1620 case BRUSH_CURVE_POW4:
1621 strength = p * p * p * p;
1622 break;
1624 strength = p * (2.0f - p);
1625 break;
1626 }
1627
1628 return strength;
1629}
1630
1631float BKE_brush_curve_strength(const Brush *br, float p, const float len)
1632{
1635}
1636
1637float BKE_brush_curve_strength_clamped(const Brush *br, float p, const float len)
1638{
1639 float strength = BKE_brush_curve_strength(br, p, len);
1640
1641 CLAMP(strength, 0.0f, 1.0f);
1642
1643 return strength;
1644}
1645
1646/* TODO: should probably be unified with BrushPainter stuff? */
1647static bool brush_gen_texture(const Brush *br,
1648 const int side,
1649 const bool use_secondary,
1650 float *rect)
1651{
1652 const MTex *mtex = (use_secondary) ? &br->mask_mtex : &br->mtex;
1653 if (mtex->tex == nullptr) {
1654 return false;
1655 }
1656
1657 const float step = 2.0 / side;
1658 int ix, iy;
1659 float x, y;
1660
1661 /* Do normalized canonical view coords for texture. */
1662 for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
1663 for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
1664 const float co[3] = {x, y, 0.0f};
1665
1666 float intensity;
1667 float rgba_dummy[4];
1668 RE_texture_evaluate(mtex, co, 0, nullptr, false, false, &intensity, rgba_dummy);
1669
1670 rect[iy * side + ix] = intensity;
1671 }
1672 }
1673
1674 return true;
1675}
1676
1677ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool display_gradient)
1678{
1679 ImBuf *im = MEM_callocN<ImBuf>("radial control texture");
1680 int side = 512;
1681 int half = side / 2;
1682
1684
1685 float *rect_float = MEM_calloc_arrayN<float>(size_t(side) * size_t(side), "radial control rect");
1687
1688 im->x = im->y = side;
1689
1690 const bool have_texture = brush_gen_texture(br, side, secondary, im->float_buffer.data);
1691
1692 if (display_gradient || have_texture) {
1693 for (int i = 0; i < side; i++) {
1694 for (int j = 0; j < side; j++) {
1695 const float magn = sqrtf(pow2f(i - half) + pow2f(j - half));
1696 const float strength = BKE_brush_curve_strength_clamped(br, magn, half);
1697 im->float_buffer.data[i * side + j] = (have_texture) ?
1698 im->float_buffer.data[i * side + j] * strength :
1699 strength;
1700 }
1701 }
1702 }
1703
1704 return im;
1705}
1706
1708{
1709 switch (paint_mode) {
1710 case PaintMode::Sculpt: {
1711 if (brush->sculpt_brush_type == SCULPT_BRUSH_TYPE_MULTIPLANE_SCRAPE) {
1712 return true;
1713 }
1714
1716 (brush->tip_roundness < 1.0f || brush->tip_scale_x != 1.0f))
1717 {
1718 return true;
1719 }
1720
1721 break;
1722 }
1723 default: {
1724 break;
1725 }
1726 }
1727
1728 return false;
1729}
1730
1731/* -------------------------------------------------------------------- */
1734
1735namespace blender::bke::brush {
1737{
1738 return !ELEM(brush.sculpt_brush_type,
1739 /* These brushes, as currently coded, cannot support dynamic topology */
1754
1755 /* These brushes could handle dynamic topology,
1756 * but user feedback indicates it's better not to */
1759}
1787{
1788 /* TODO: Should this support Face Sets...? */
1789 return !ELEM(brush.sculpt_brush_type,
1794}
1796{
1797 return brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_LAYER;
1798}
1800{
1801 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_PLANE);
1802}
1804{
1805 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_PLANE);
1806}
1808{
1809 return !(brush.flag & BRUSH_ANCHORED) && !(brush.flag & BRUSH_DRAG_DOT) &&
1810 !ELEM(brush.sculpt_brush_type,
1815}
1824{
1825 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_SNAKE_HOOK);
1826}
1828{
1829 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_LAYER, SCULPT_BRUSH_TYPE_CLOTH);
1830}
1832{
1833 return ELEM(brush.sculpt_brush_type,
1837}
1855{
1856 /* TODO: Should the face set brush be here...? */
1857 return !ELEM(brush.sculpt_brush_type,
1862}
1864{
1865 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_PAINT);
1866}
1883{
1884 return !(brush.flag & BRUSH_ANCHORED) && !(brush.flag & BRUSH_DRAG_DOT) &&
1885 !(brush.flag & BRUSH_LINE) && !(brush.flag & BRUSH_CURVE) &&
1886 !ELEM(brush.sculpt_brush_type,
1891}
1901
1908static bool is_grab_tool(const Brush &brush)
1909{
1910 return (brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_CLOTH &&
1911 brush.cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) ||
1912 ELEM(brush.sculpt_brush_type,
1920}
1922{
1923 return !is_grab_tool(brush);
1924}
1926{
1927 return !is_grab_tool(brush);
1928}
1930{
1931 return !is_grab_tool(brush);
1932}
1934{
1935 return !is_grab_tool(brush);
1936}
1975} // namespace blender::bke::brush
1976
void BKE_asset_metadata_idprop_ensure(AssetMetaData *asset_data, IDProperty *prop)
Definition asset.cc:168
void BKE_colorband_foreach_working_space_color(ColorBand *coba, const IDTypeForeachColorFunctionCallback &fn)
Definition colorband.cc:652
void BKE_curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, CurveMapSlopeType slope)
float BKE_curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value)
void BKE_curvemapping_blend_read(BlendDataReader *reader, CurveMapping *cumap)
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_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:49
@ IDTYPE_FLAGS_NO_MEMFILE_UNDO
Definition BKE_idtype.hh:58
IDTypeInfo IDType_ID_BR
Definition brush.cc:522
ID * BKE_id_copy_for_duplicate(Main *bmain, ID *id, eDupli_ID_Flags duplicate_flags, int copy_flags)
Definition lib_id.cc:787
void BKE_id_delete(Main *bmain, void *idv) ATTR_NONNULL()
@ LIB_ID_MAKELOCAL_FULL_LIBRARY
void BKE_lib_id_expand_local(Main *bmain, ID *id, int flags)
Definition lib_id.cc:481
void id_fake_user_set(ID *id)
Definition lib_id.cc:396
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:2001
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:502
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition lib_id.cc:782
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1514
@ LIB_ID_COPY_NO_PREVIEW
@ LIB_ID_COPY_DEFAULT
void id_us_min(ID *id)
Definition lib_id.cc:366
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:2631
#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
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:931
void void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, int remap_flags) ATTR_NONNULL(1
@ ID_REMAP_SKIP_USER_CLEAR
@ ID_REMAP_SKIP_INDIRECT_USAGE
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:583
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:577
General operations, lookup, etc. for materials.
CurveMapping * BKE_sculpt_default_cavity_curve()
Definition scene.cc:131
CurveMapping * BKE_paint_default_curve()
Definition scene.cc:146
bool BKE_paint_use_unified_color(const Paint *paint)
Definition paint.cc:601
std::optional< int > BKE_paint_get_brush_type_from_obmode(const Brush *brush, eObjectMode ob_mode)
Definition paint.cc:1312
PaintMode
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:217
#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)
void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
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)
#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.
#define ID_EXTRA_USERS(id)
Definition DNA_ID.h:662
@ ID_TAG_NEW
Definition DNA_ID.h:919
@ ID_TAG_INDIRECT
Definition DNA_ID.h:848
#define FILTER_ID_MA
Definition DNA_ID.h:1208
#define FILTER_ID_BR
Definition DNA_ID.h:1199
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
#define FILTER_ID_TE
Definition DNA_ID.h:1220
@ INDEX_ID_BR
Definition DNA_ID.h:1346
#define ID_REAL_USERS(id)
Definition DNA_ID.h:676
#define FILTER_ID_PC
Definition DNA_ID.h:1216
#define ID_NEW_SET(_id, _idn)
Definition DNA_ID.h:756
#define FILTER_ID_IM
Definition DNA_ID.h:1204
@ ID_FLAG_FAKEUSER
Definition DNA_ID.h:769
@ 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_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_CLOTH_DEFORM_GRAB
@ 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
@ BRUSH_JITTER_COLOR
#define MAX_BRUSH_PIXEL_DIAMETER
@ 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)
void IMB_assign_float_buffer(ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership)
@ IB_DO_NOT_TAKE_OWNERSHIP
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
BMesh const char void * data
void BKE_brush_scale_unprojected_size(float *unprojected_size, int new_brush_size, int old_brush_size)
Definition brush.cc:1320
float BKE_brush_unprojected_size_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1308
const MTex * BKE_brush_mask_texture_get(const Brush *brush, const eObjectMode object_mode)
Definition brush.cc:904
float BKE_brush_curve_strength_clamped(const Brush *br, float p, const float len)
Definition brush.cc:1637
static void brush_defaults(Brush *brush)
Definition brush.cc:571
bool BKE_brush_use_alpha_pressure(const Brush *brush)
Definition brush.cc:1290
float BKE_brush_alpha_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1357
float BKE_brush_curve_strength(const eBrushCurvePreset preset, const CurveMapping *cumap, const float distance, const float brush_radius)
Definition brush.cc:1577
void BKE_brush_color_sync_legacy(Brush *brush)
Definition brush.cc:1227
static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition brush.cc:242
#define BR_TEST(field, t)
static void brush_free_data(ID *id)
Definition brush.cc:140
const float * BKE_brush_color_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1161
static AssetTypeInfo AssetType_BR
Definition brush.cc:517
void BKE_brush_input_samples_set(Paint *paint, Brush *brush, int value)
Definition brush.cc:1391
static void brush_blend_read_after_liblink(BlendLibReader *, ID *id)
Definition brush.cc:456
float BKE_brush_sample_tex_3d(const Paint *paint, const Brush *br, const MTex *mtex, const float point[3], float rgba[4], const int thread, ImagePool *pool)
Definition brush.cc:920
const MTex * BKE_brush_color_texture_get(const Brush *brush, const eObjectMode object_mode)
Definition brush.cc:912
const float * BKE_brush_secondary_color_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1205
Brush * BKE_brush_first_search(Main *bmain, const eObjectMode ob_mode)
Definition brush.cc:771
void BKE_brush_scale_size(int *r_brush_size, float new_unprojected_size, float old_unprojected_size)
Definition brush.cc:1332
static void brush_foreach_id(ID *id, LibraryForeachIDData *data)
Definition brush.cc:215
#define FROM_DEFAULT(member)
#define BR_TEST_FLAG_OVERLAY(_f)
bool BKE_brush_use_locked_size(const Paint *paint, const Brush *brush)
Definition brush.cc:1277
std::optional< BrushColorJitterSettings > BKE_brush_color_jitter_get_settings(const Paint *paint, const Brush *brush)
Definition brush.cc:1170
bool BKE_brush_use_size_pressure(const Brush *brush)
Definition brush.cc:1285
float BKE_brush_radius_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1272
static void brush_init_data(ID *id)
Definition brush.cc:55
bool BKE_brush_has_cube_tip(const Brush *brush, PaintMode paint_mode)
Definition brush.cc:1707
void BKE_brush_randomize_texture_coords(Paint *paint, bool mask)
Definition brush.cc:1433
static void brush_make_local(Main *bmain, ID *id, const int flags)
Definition brush.cc:178
static void brush_copy_data(Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int flag)
Definition brush.cc:79
void BKE_brush_init_curves_sculpt_settings(Brush *brush)
Definition brush.cc:748
Brush * BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode)
Definition brush.cc:627
void BKE_brush_system_init()
Definition brush.cc:556
#define FROM_DEFAULT_PTR(member)
ImBuf * BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool display_gradient)
Definition brush.cc:1677
static bool brush_gen_texture(const Brush *br, const int side, const bool use_secondary, float *rect)
Definition brush.cc:1647
static RNG * brush_rng
Definition brush.cc:554
void BKE_brush_curve_preset(Brush *b, eCurveMappingPreset preset)
Definition brush.cc:886
static void brush_blend_read_data(BlendDataReader *reader, ID *id)
Definition brush.cc:319
void BKE_brush_color_set(Paint *paint, Brush *brush, const float color[3])
Definition brush.cc:1213
float BKE_brush_unprojected_radius_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1315
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:1448
void BKE_brush_jitter_pos(const Paint &paint, const Brush &brush, const float pos[2], float jitterpos[2])
Definition brush.cc:1406
void BKE_brush_size_set(Paint *paint, Brush *brush, int size)
Definition brush.cc:1248
void BKE_brush_init_gpencil_settings(Brush *brush)
Definition brush.cc:648
Brush * BKE_brush_duplicate(Main *bmain, Brush *brush, eDupli_ID_Flags, uint duplicate_options)
Definition brush.cc:690
void BKE_brush_debug_print_state(Brush *br)
Definition brush.cc:781
void BKE_brush_unprojected_size_set(Paint *paint, Brush *brush, float unprojected_size)
Definition brush.cc:1295
bool BKE_brush_delete(Main *bmain, Brush *brush)
Definition brush.cc:674
void BKE_brush_weight_set(Paint *paint, Brush *brush, float value)
Definition brush.cc:1371
void BKE_brush_alpha_set(Paint *paint, Brush *brush, float alpha)
Definition brush.cc:1344
static void brush_asset_metadata_ensure(void *asset_ptr, AssetMetaData *asset_data)
Definition brush.cc:473
int BKE_brush_input_samples_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1384
void BKE_brush_tag_unsaved_changes(Brush *brush)
Definition brush.cc:764
static void brush_foreach_working_space_color(ID *id, const IDTypeForeachColorFunctionCallback &fn)
Definition brush.cc:229
#define BR_TEST_FLAG(_f)
int BKE_brush_size_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1264
float BKE_brush_sample_masktex(const Paint *paint, Brush *br, const float point[2], const int thread, ImagePool *pool)
Definition brush.cc:1043
float BKE_brush_weight_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1364
void BKE_brush_system_exit()
Definition brush.cc:562
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
nullptr float
#define GS(x)
uint pos
#define printf(...)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
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:1854
bool supports_secondary_cursor_color(const Brush &brush)
Definition brush.cc:1867
bool supports_auto_smooth(const Brush &brush)
Definition brush.cc:1786
bool supports_jitter(const Brush &brush)
Definition brush.cc:1807
bool supports_space_attenuation(const Brush &brush)
Definition brush.cc:1892
bool supports_size_pressure(const Brush &brush)
Definition brush.cc:1925
bool supports_persistence(const Brush &brush)
Definition brush.cc:1827
bool supports_tilt(const Brush &brush)
Definition brush.cc:1967
bool supports_inverted_direction(const Brush &brush)
Definition brush.cc:1937
bool supports_auto_smooth_pressure(const Brush &brush)
Definition brush.cc:1929
bool supports_rake_factor(const Brush &brush)
Definition brush.cc:1823
bool supports_plane_depth(const Brush &brush)
Definition brush.cc:1803
bool supports_accumulate(const Brush &brush)
Definition brush.cc:1760
static bool is_grab_tool(const Brush &brush)
Definition brush.cc:1908
bool supports_gravity(const Brush &brush)
Definition brush.cc:1954
bool supports_hardness_pressure(const Brush &brush)
Definition brush.cc:1933
bool supports_smooth_stroke(const Brush &brush)
Definition brush.cc:1882
bool supports_plane_offset(const Brush &brush)
Definition brush.cc:1838
bool supports_pinch_factor(const Brush &brush)
Definition brush.cc:1831
bool supports_color(const Brush &brush)
Definition brush.cc:1863
bool supports_random_texture_angle(const Brush &brush)
Definition brush.cc:1846
bool supports_strength_pressure(const Brush &brush)
Definition brush.cc:1921
bool supports_dyntopo(const Brush &brush)
Definition brush.cc:1736
bool supports_height(const Brush &brush)
Definition brush.cc:1795
bool supports_topology_rake(const Brush &brush)
Definition brush.cc:1775
bool supports_plane_height(const Brush &brush)
Definition brush.cc:1799
bool supports_normal_weight(const Brush &brush)
Definition brush.cc:1816
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:257
const char * name
#define fabsf
#define sqrtf
#define sinf
#define cosf
#define atan2f
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
float secondary_color[3]
struct ColorBand * gradient
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct MTex mtex
float stencil_pos[2]
float stencil_dimension[2]
struct CurveMapping * curve_jitter
float texture_sample_bias
struct CurveMapping * curve_rand_value
struct CurveMapping * curve_distance_falloff
float mask_stencil_pos[2]
struct BrushGpencilSettings * gpencil_settings
char has_unsaved_changes
PreviewImage * preview
struct CurveMapping * automasking_cavity_curve
struct BrushCurvesSculptSettings * curves_sculpt_settings
struct MTex mask_mtex
int mask_pressure
float mask_stencil_dimension[2]
int curve_distance_falloff_preset
struct PaintCurve * paint_curve
struct CurveMapping * curve_size
float color[3]
struct CurveMapping * curve_strength
const blender::FunctionRef< void(float rgb[3])> single
Definition DNA_ID.h:414
int tag
Definition DNA_ID.h:442
int us
Definition DNA_ID.h:443
short flag
Definition DNA_ID.h:438
ImBufFloatBuffer float_buffer
char brush_map_mode
struct Tex * tex
ListBase brushes
Definition BKE_main.hh:302
Definition rand.cc:33
struct CurveMapping * curve_rand_value
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
const blender::ocio::ColorSpace * 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:145