Blender V4.3
paint.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 by Nicholas Bishop. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstdlib>
10#include <cstring>
11#include <optional>
12
13#include "DNA_object_enums.h"
14#include "MEM_guardedalloc.h"
15
16#include "DNA_asset_types.h"
17#include "DNA_brush_types.h"
18#include "DNA_defaults.h"
20#include "DNA_key_types.h"
21#include "DNA_mesh_types.h"
22#include "DNA_meshdata_types.h"
23#include "DNA_modifier_types.h"
24#include "DNA_object_types.h"
25#include "DNA_scene_types.h"
26#include "DNA_space_types.h"
27#include "DNA_view3d_types.h"
28#include "DNA_workspace_types.h"
29
30#include "BLI_bitmap.h"
31#include "BLI_hash.h"
32#include "BLI_listbase.h"
33#include "BLI_math_color.h"
34#include "BLI_math_matrix.h"
35#include "BLI_math_matrix.hh"
36#include "BLI_math_vector.h"
37#include "BLI_string.h"
38#include "BLI_string_utf8.h"
39#include "BLI_utildefines.h"
40#include "BLI_vector.hh"
41
42#include "BLT_translation.hh"
43
44#include "BKE_asset.hh"
45#include "BKE_asset_edit.hh"
46#include "BKE_attribute.hh"
47#include "BKE_brush.hh"
48#include "BKE_ccg.hh"
49#include "BKE_colortools.hh"
50#include "BKE_context.hh"
51#include "BKE_crazyspace.hh"
52#include "BKE_deform.hh"
53#include "BKE_gpencil_legacy.h"
54#include "BKE_idtype.hh"
55#include "BKE_image.hh"
56#include "BKE_key.hh"
57#include "BKE_layer.hh"
58#include "BKE_lib_id.hh"
59#include "BKE_main.hh"
60#include "BKE_material.h"
61#include "BKE_mesh.hh"
62#include "BKE_mesh_mapping.hh"
63#include "BKE_mesh_runtime.hh"
64#include "BKE_modifier.hh"
65#include "BKE_multires.hh"
66#include "BKE_object.hh"
67#include "BKE_object_types.hh"
68#include "BKE_paint.hh"
69#include "BKE_pbvh_api.hh"
70#include "BKE_scene.hh"
71#include "BKE_subdiv_ccg.hh"
72#include "BKE_subsurf.hh"
73
74#include "DEG_depsgraph.hh"
76
77#include "RNA_enum_types.hh"
78
79#include "BLO_read_write.hh"
80
81#include "bmesh.hh"
82
83using blender::float3;
85using blender::Span;
86using blender::Vector;
88
89static void palette_init_data(ID *id)
90{
91 Palette *palette = (Palette *)id;
92
94
95 /* Enable fake user by default. */
96 id_fake_user_set(&palette->id);
97}
98
99static void palette_copy_data(Main * /*bmain*/,
100 std::optional<Library *> /*owner_library*/,
101 ID *id_dst,
102 const ID *id_src,
103 const int /*flag*/)
104{
105 Palette *palette_dst = (Palette *)id_dst;
106 const Palette *palette_src = (const Palette *)id_src;
107
108 BLI_duplicatelist(&palette_dst->colors, &palette_src->colors);
109}
110
111static void palette_free_data(ID *id)
112{
113 Palette *palette = (Palette *)id;
114
115 BLI_freelistN(&palette->colors);
116}
117
118static void palette_blend_write(BlendWriter *writer, ID *id, const void *id_address)
119{
120 Palette *palette = (Palette *)id;
121
122 BLO_write_id_struct(writer, Palette, id_address, &palette->id);
123 BKE_id_blend_write(writer, &palette->id);
124
125 BLO_write_struct_list(writer, PaletteColor, &palette->colors);
126}
127
129{
130 Palette *palette = (Palette *)id;
131 BLO_read_struct_list(reader, PaletteColor, &palette->colors);
132}
133
134static void palette_undo_preserve(BlendLibReader * /*reader*/, ID *id_new, ID *id_old)
135{
136 /* Whole Palette is preserved across undo-steps, and it has no extra pointer, simple. */
137 /* NOTE: We do not care about potential internal references to self here, Palette has none. */
138 /* NOTE: We do not swap IDProperties, as dealing with potential ID pointers in those would be
139 * fairly delicate. */
140 BKE_lib_id_swap(nullptr, id_new, id_old, false, 0);
141 std::swap(id_new->properties, id_old->properties);
142}
143
145 /*id_code*/ ID_PAL,
146 /*id_filter*/ FILTER_ID_PAL,
147 /*dependencies_id_types*/ 0,
148 /*main_listbase_index*/ INDEX_ID_PAL,
149 /*struct_size*/ sizeof(Palette),
150 /*name*/ "Palette",
151 /*name_plural*/ N_("palettes"),
152 /*translation_context*/ BLT_I18NCONTEXT_ID_PALETTE,
153 /*flags*/ IDTYPE_FLAGS_NO_ANIMDATA,
154 /*asset_type_info*/ nullptr,
155
156 /*init_data*/ palette_init_data,
157 /*copy_data*/ palette_copy_data,
158 /*free_data*/ palette_free_data,
159 /*make_local*/ nullptr,
160 /*foreach_id*/ nullptr,
161 /*foreach_cache*/ nullptr,
162 /*foreach_path*/ nullptr,
163 /*owner_pointer_get*/ nullptr,
164
165 /*blend_write*/ palette_blend_write,
166 /*blend_read_data*/ palette_blend_read_data,
167 /*blend_read_after_liblink*/ nullptr,
168
169 /*blend_read_undo_preserve*/ palette_undo_preserve,
170
171 /*lib_override_apply_post*/ nullptr,
172};
173
174static void paint_curve_copy_data(Main * /*bmain*/,
175 std::optional<Library *> /*owner_library*/,
176 ID *id_dst,
177 const ID *id_src,
178 const int /*flag*/)
179{
180 PaintCurve *paint_curve_dst = (PaintCurve *)id_dst;
181 const PaintCurve *paint_curve_src = (const PaintCurve *)id_src;
182
183 if (paint_curve_src->tot_points != 0) {
184 paint_curve_dst->points = static_cast<PaintCurvePoint *>(
185 MEM_dupallocN(paint_curve_src->points));
186 }
187}
188
189static void paint_curve_free_data(ID *id)
190{
191 PaintCurve *paint_curve = (PaintCurve *)id;
192
193 MEM_SAFE_FREE(paint_curve->points);
194 paint_curve->tot_points = 0;
195}
196
197static void paint_curve_blend_write(BlendWriter *writer, ID *id, const void *id_address)
198{
199 PaintCurve *pc = (PaintCurve *)id;
200
201 BLO_write_id_struct(writer, PaintCurve, id_address, &pc->id);
202 BKE_id_blend_write(writer, &pc->id);
203
205}
206
208{
209 PaintCurve *pc = (PaintCurve *)id;
211}
212
214 /*id_code*/ ID_PC,
215 /*id_filter*/ FILTER_ID_PC,
216 /*dependencies_id_types*/ 0,
217 /*main_listbase_index*/ INDEX_ID_PC,
218 /*struct_size*/ sizeof(PaintCurve),
219 /*name*/ "PaintCurve",
220 /*name_plural*/ N_("paint_curves"),
221 /*translation_context*/ BLT_I18NCONTEXT_ID_PAINTCURVE,
222 /*flags*/ IDTYPE_FLAGS_NO_ANIMDATA,
223 /*asset_type_info*/ nullptr,
224
225 /*init_data*/ nullptr,
226 /*copy_data*/ paint_curve_copy_data,
227 /*free_data*/ paint_curve_free_data,
228 /*make_local*/ nullptr,
229 /*foreach_id*/ nullptr,
230 /*foreach_cache*/ nullptr,
231 /*foreach_path*/ nullptr,
232 /*owner_pointer_get*/ nullptr,
233
234 /*blend_write*/ paint_curve_blend_write,
235 /*blend_read_data*/ paint_curve_blend_read_data,
236 /*blend_read_after_liblink*/ nullptr,
237
238 /*blend_read_undo_preserve*/ nullptr,
239
240 /*lib_override_apply_post*/ nullptr,
241};
242
243const uchar PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
244const uchar PAINT_CURSOR_VERTEX_PAINT[3] = {255, 255, 255};
245const uchar PAINT_CURSOR_WEIGHT_PAINT[3] = {200, 200, 255};
246const uchar PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255};
247const uchar PAINT_CURSOR_SCULPT_CURVES[3] = {255, 100, 100};
248const uchar PAINT_CURSOR_PAINT_GREASE_PENCIL[3] = {255, 100, 100};
249const uchar PAINT_CURSOR_SCULPT_GREASE_PENCIL[3] = {255, 100, 100};
250
252
253void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex)
254{
255 Paint *paint = BKE_paint_get_active(scene, view_layer);
256 if (!paint) {
257 return;
258 }
259
260 Brush *br = BKE_paint_brush(paint);
261 if (!br) {
262 return;
263 }
264
265 if (br->mtex.tex == tex) {
267 }
268 if (br->mask_mtex.tex == tex) {
270 }
271}
272
274{
275 Paint *paint = BKE_paint_get_active(scene, view_layer);
276 if (paint == nullptr) {
277 return;
278 }
279
280 Brush *br = BKE_paint_brush(paint);
281 if (br && br->curve == curve) {
283 }
284}
285
291
296
314
319
321{
322 ToolSettings *ts = sce->toolsettings;
323 Paint **paint_ptr = nullptr;
324 /* Some paint modes don't store paint settings as pointer, for these this can be set and
325 * referenced by paint_ptr. */
326 Paint *paint_tmp = nullptr;
327
328 switch (mode) {
330 paint_ptr = (Paint **)&ts->sculpt;
331 break;
333 paint_ptr = (Paint **)&ts->vpaint;
334 break;
336 paint_ptr = (Paint **)&ts->wpaint;
337 break;
340 paint_tmp = (Paint *)&ts->imapaint;
341 paint_ptr = &paint_tmp;
342 break;
344 paint_ptr = (Paint **)&ts->gp_paint;
345 break;
347 paint_ptr = (Paint **)&ts->gp_vertexpaint;
348 break;
350 paint_ptr = (Paint **)&ts->gp_sculptpaint;
351 break;
353 paint_ptr = (Paint **)&ts->gp_weightpaint;
354 break;
356 paint_ptr = (Paint **)&ts->curves_sculpt;
357 break;
359 paint_ptr = (Paint **)&ts->gp_sculptpaint;
360 break;
362 break;
363 }
364 if (paint_ptr) {
365 BKE_paint_ensure(ts, paint_ptr);
366 return true;
367 }
368 return false;
369}
370
372{
373 if (sce) {
374 ToolSettings *ts = sce->toolsettings;
375
376 switch (mode) {
378 return &ts->sculpt->paint;
380 return &ts->vpaint->paint;
382 return &ts->wpaint->paint;
385 return &ts->imapaint.paint;
387 return &ts->gp_paint->paint;
389 return &ts->gp_vertexpaint->paint;
391 return &ts->gp_sculptpaint->paint;
393 return &ts->gp_weightpaint->paint;
395 return &ts->curves_sculpt->paint;
397 return &ts->gp_sculptpaint->paint;
399 return nullptr;
400 default:
401 return &ts->imapaint.paint;
402 }
403 }
404
405 return nullptr;
406}
407
437
439{
440 if (sce && view_layer) {
441 ToolSettings *ts = sce->toolsettings;
442 BKE_view_layer_synced_ensure(sce, view_layer);
443 Object *actob = BKE_view_layer_active_object_get(view_layer);
444
445 if (actob) {
446 switch (actob->mode) {
447 case OB_MODE_SCULPT:
448 return &ts->sculpt->paint;
450 return &ts->vpaint->paint;
452 return &ts->wpaint->paint;
454 return &ts->imapaint.paint;
456 return &ts->gp_paint->paint;
458 return &ts->gp_vertexpaint->paint;
460 return &ts->gp_sculptpaint->paint;
462 return &ts->gp_weightpaint->paint;
464 return &ts->curves_sculpt->paint;
465 default:
466 break;
467 }
468 }
469
470 /* default to image paint */
471 return &ts->imapaint.paint;
472 }
473
474 return nullptr;
475}
476
478{
479 Scene *sce = CTX_data_scene(C);
480 ViewLayer *view_layer = CTX_data_view_layer(C);
481 SpaceImage *sima;
482
483 if (sce && view_layer) {
484 ToolSettings *ts = sce->toolsettings;
485 BKE_view_layer_synced_ensure(sce, view_layer);
486 Object *obact = BKE_view_layer_active_object_get(view_layer);
487
488 if ((sima = CTX_wm_space_image(C)) != nullptr) {
489 if (obact && obact->mode == OB_MODE_EDIT) {
490 if (sima->mode == SI_MODE_PAINT) {
491 return &ts->imapaint.paint;
492 }
493 }
494 else {
495 return &ts->imapaint.paint;
496 }
497 }
498 else {
499 return BKE_paint_get_active(sce, view_layer);
500 }
501 }
502
503 return nullptr;
504}
505
507{
508 Scene *sce = CTX_data_scene(C);
509 ViewLayer *view_layer = CTX_data_view_layer(C);
510 SpaceImage *sima;
511
512 if (sce && view_layer) {
513 BKE_view_layer_synced_ensure(sce, view_layer);
514 Object *obact = BKE_view_layer_active_object_get(view_layer);
515
516 if ((sima = CTX_wm_space_image(C)) != nullptr) {
517 if (obact && obact->mode == OB_MODE_EDIT) {
518 if (sima->mode == SI_MODE_PAINT) {
520 }
521 }
522 else {
524 }
525 }
526 else if (obact) {
527 switch (obact->mode) {
528 case OB_MODE_SCULPT:
529 return PaintMode::Sculpt;
531 if (obact->type == OB_GPENCIL_LEGACY) {
533 }
534 if (obact->type == OB_GREASE_PENCIL) {
536 }
537 return PaintMode::Invalid;
539 return PaintMode::GPencil;
545 return PaintMode::Vertex;
547 return PaintMode::Weight;
552 default:
554 }
555 }
556 else {
557 /* default to image paint */
559 }
560 }
561
562 return PaintMode::Invalid;
563}
564
604
605bool BKE_paint_use_unified_color(const ToolSettings *tool_settings, const Paint *paint)
606{
607 /* Grease pencil draw mode never uses unified paint. */
609 return false;
610 }
611
612 return tool_settings->unified_paint_settings.flag & UNIFIED_PAINT_COLOR;
613}
614
620{
621 /* Don't resolve this during file read, it will be done after. */
622 if (bmain->is_locked_for_linking) {
623 return false;
624 }
625 /* Attempt to restore a valid active brush from brush asset information. */
626 if (paint->brush != nullptr) {
627 return false;
628 }
629 if (paint->brush_asset_reference == nullptr) {
630 return false;
631 }
632
634 *bmain, ID_BR, *paint->brush_asset_reference));
635 BLI_assert(brush == nullptr || blender::bke::asset_edit_id_is_editable(brush->id));
636
637 /* Ensure we have a brush with appropriate mode to assign.
638 * Could happen if contents of asset blend was manually changed. */
639 if (brush == nullptr || (paint->runtime.ob_mode & brush->ob_mode) == 0) {
640 MEM_delete(paint->brush_asset_reference);
641 paint->brush_asset_reference = nullptr;
642 return false;
643 }
644
645 paint->brush = brush;
646 return true;
647}
648
650{
651 return (Brush *)BKE_paint_brush_for_read((const Paint *)paint);
652}
653
655{
656 return paint ? paint->brush : nullptr;
657}
658
659bool BKE_paint_brush_poll(const Paint *paint, const Brush *brush)
660{
661 if (paint == nullptr) {
662 return false;
663 }
664 return !brush || (paint->runtime.ob_mode & brush->ob_mode) != 0;
665}
666
668{
669 if (std::optional<AssetWeakReference> weak_ref = blender::bke::asset_edit_weak_reference_from_id(
670 brush->id))
671 {
672 return MEM_new<AssetWeakReference>(__func__, *weak_ref);
673 }
674
675 return nullptr;
676}
677
679 Paint *paint,
680 const AssetWeakReference *brush_asset_reference)
681{
682 /* Don't resolve this during file read, it will be done after. */
683 if (bmain->is_locked_for_linking) {
684 return false;
685 }
686
687 Brush *brush = reinterpret_cast<Brush *>(
688 blender::bke::asset_edit_id_from_weak_reference(*bmain, ID_BR, *brush_asset_reference));
689 BLI_assert(brush == nullptr || !ID_IS_LINKED(brush) ||
691
692 /* Ensure we have a brush with appropriate mode to assign.
693 * Could happen if contents of asset blend were manually changed. */
694 if (!BKE_paint_brush_poll(paint, brush)) {
695 return false;
696 }
697
698 /* Update the brush itself. */
699 paint->brush = brush;
700 /* Update the brush asset reference. */
701 {
702 MEM_delete(paint->brush_asset_reference);
703 paint->brush_asset_reference = nullptr;
704 if (brush != nullptr) {
706 *brush_asset_reference);
707 paint->brush_asset_reference = MEM_new<AssetWeakReference>(__func__, *brush_asset_reference);
708 }
709 }
710
711 return true;
712}
713
714bool BKE_paint_brush_set(Paint *paint, Brush *brush)
715{
716 if (!BKE_paint_brush_poll(paint, brush)) {
717 return false;
718 }
719
720 paint->brush = brush;
721
722 MEM_delete(paint->brush_asset_reference);
723 paint->brush_asset_reference = nullptr;
724 if (brush != nullptr) {
726 }
727
728 return true;
729}
730
732{
733 switch (ob_mode) {
734 case OB_MODE_SCULPT:
735 return "essentials_brushes-mesh_sculpt.blend";
737 return "essentials_brushes-mesh_vertex.blend";
739 return "essentials_brushes-mesh_weight.blend";
741 return "essentials_brushes-mesh_texture.blend";
743 return "essentials_brushes-gp_draw.blend";
745 return "essentials_brushes-gp_sculpt.blend";
747 return "essentials_brushes-gp_weight.blend";
749 return "essentials_brushes-gp_vertex.blend";
751 return "essentials_brushes-curve_sculpt.blend";
752 default:
753 return nullptr;
754 }
755}
756
758 const char *name, const eObjectMode ob_mode)
759{
760 const char *essentials_file_name = paint_brush_essentials_asset_file_name_from_obmode(ob_mode);
761 if (!essentials_file_name) {
762 return nullptr;
763 }
764
765 AssetWeakReference *weak_ref = MEM_new<AssetWeakReference>(__func__);
766 weak_ref->asset_library_type = eAssetLibraryType::ASSET_LIBRARY_ESSENTIALS;
767 weak_ref->asset_library_identifier = nullptr;
769 "brushes/%s/Brush/%s", essentials_file_name, name);
770 return weak_ref;
771}
772
773static std::optional<AssetWeakReference> paint_brush_asset_reference_from_essentials(
774 const char *name, const eObjectMode ob_mode)
775{
776 const char *essentials_file_name = paint_brush_essentials_asset_file_name_from_obmode(ob_mode);
777 if (!essentials_file_name) {
778 return {};
779 }
780
781 AssetWeakReference weak_ref;
782 weak_ref.asset_library_type = eAssetLibraryType::ASSET_LIBRARY_ESSENTIALS;
783 weak_ref.asset_library_identifier = nullptr;
785 "brushes/%s/Brush/%s", essentials_file_name, name);
786 return weak_ref;
787}
788
789Brush *BKE_paint_brush_from_essentials(Main *bmain, const eObjectMode ob_mode, const char *name)
790{
791 std::optional<AssetWeakReference> weak_ref = paint_brush_asset_reference_from_essentials(
792 name, ob_mode);
793 if (!weak_ref) {
794 return nullptr;
795 }
796
797 return reinterpret_cast<Brush *>(
799}
800
801static void paint_brush_set_essentials_reference(Paint *paint, const char *name)
802{
803 /* Set brush asset reference to a named brush in the essentials asset library. */
804 MEM_delete(paint->brush_asset_reference);
805
808 name, eObjectMode(paint->runtime.ob_mode));
809 paint->brush = nullptr;
810}
811
812static void paint_eraser_brush_set_essentials_reference(Paint *paint, const char *name)
813{
814 /* Set brush asset reference to a named brush in the essentials asset library. */
815 MEM_delete(paint->eraser_brush_asset_reference);
816
819 name, eObjectMode(paint->runtime.ob_mode));
820 paint->eraser_brush = nullptr;
821}
822
824 eObjectMode ob_mode,
825 std::optional<int> brush_type,
827 blender::StringRefNull *r_eraser_name = nullptr)
828{
829 const char *name = "";
830 const char *eraser_name = "";
831
832 switch (ob_mode) {
833 case OB_MODE_SCULPT:
834 name = "Draw";
835 if (brush_type) {
836 switch (eBrushSculptType(*brush_type)) {
838 name = "Mask";
839 break;
841 name = "Face Set Paint";
842 break;
844 name = "Paint Hard";
845 break;
847 name = "Density";
848 break;
850 name = "Erase Multires Displacement";
851 break;
853 name = "Smear Multires Displacement";
854 break;
855 default:
856 break;
857 }
858 }
859 break;
861 name = "Paint Hard";
862 if (brush_type) {
863 switch (eBrushVertexPaintType(*brush_type)) {
865 name = "Blur";
866 break;
868 name = "Average";
869 break;
871 name = "Smear";
872 break;
874 /* Use default, don't override. */
875 break;
876 }
877 }
878 break;
880 name = "Paint";
881 if (brush_type) {
882 switch (eBrushWeightPaintType(*brush_type)) {
884 name = "Blur";
885 break;
887 name = "Average";
888 break;
890 name = "Smear";
891 break;
893 /* Use default, don't override. */
894 break;
895 }
896 }
897 break;
899 name = "Paint Hard";
900 if (brush_type) {
901 switch (eBrushImagePaintType(*brush_type)) {
903 name = "Blur";
904 break;
906 name = "Smear";
907 break;
909 name = "Fill";
910 break;
912 name = "Mask";
913 break;
915 name = "Clone";
916 break;
918 break;
919 }
920 }
921 break;
923 name = "Comb";
924 if (brush_type) {
925 switch (eBrushCurvesSculptType(*brush_type)) {
927 name = "Add";
928 break;
930 name = "Delete";
931 break;
933 name = "Density";
934 break;
936 name = "Select";
937 break;
938 default:
939 break;
940 }
941 }
942 break;
944 name = "Pencil";
945 /* Different default brush for some brush types. */
946 if (brush_type) {
947 switch (eBrushGPaintType(*brush_type)) {
949 name = "Eraser Hard";
950 break;
952 name = "Fill";
953 break;
956 /* Use default, don't override. */
957 break;
958 }
959 }
960 eraser_name = "Eraser Soft";
961 break;
963 name = "Paint";
964 if (brush_type) {
965 switch (eBrushGPVertexType(*brush_type)) {
967 name = "Blur";
968 break;
970 name = "Average";
971 break;
973 name = "Smear";
974 break;
976 name = "Replace";
977 break;
979 /* Use default, don't override. */
980 break;
982 /* Unused brush type. */
984 break;
985 }
986 }
987 break;
989 name = "Smooth";
990 if (brush_type) {
991 switch (eBrushGPSculptType(*brush_type)) {
993 name = "Clone";
994 break;
995 default:
996 break;
997 }
998 }
999 break;
1001 name = "Paint";
1002 if (brush_type) {
1003 switch (eBrushGPWeightType(*brush_type)) {
1005 name = "Blur";
1006 break;
1008 name = "Average";
1009 break;
1011 name = "Smear";
1012 break;
1014 /* Use default, don't override. */
1015 break;
1016 }
1017 }
1018 break;
1019 default:
1021 break;
1022 }
1023
1024 *r_name = name;
1025 if (r_eraser_name) {
1026 *r_eraser_name = eraser_name;
1027 }
1028}
1029
1030std::optional<AssetWeakReference> BKE_paint_brush_type_default_reference(
1031 eObjectMode ob_mode, std::optional<int> brush_type)
1032{
1034
1035 paint_brush_default_essentials_name_get(ob_mode, brush_type, &name, nullptr);
1036 if (name.is_empty()) {
1037 return {};
1038 }
1039
1040 return paint_brush_asset_reference_from_essentials(name.c_str(), ob_mode);
1041}
1042
1044 const bool do_regular = true,
1045 const bool do_eraser = true)
1046{
1047 if (!paint->runtime.initialized) {
1048 /* Can happen when loading old file where toolsettings are created in versioning, without
1049 * calling #paint_runtime_init(). Will be done later when necessary. */
1050 return;
1051 }
1052
1054 blender::StringRefNull eraser_name;
1055
1057 eObjectMode(paint->runtime.ob_mode), std::nullopt, &name, &eraser_name);
1058
1059 if (do_regular && !name.is_empty()) {
1060 paint_brush_set_essentials_reference(paint, name.c_str());
1061 }
1062 if (do_eraser && !eraser_name.is_empty()) {
1064 }
1065}
1066
1095
1097{
1098 paint_brush_set_default_reference(paint, true, false);
1099 return paint_brush_update_from_asset_reference(bmain, paint);
1100}
1101
1102bool BKE_paint_brush_set_essentials(Main *bmain, Paint *paint, const char *name)
1103{
1105 return paint_brush_update_from_asset_reference(bmain, paint);
1106}
1107
1109{
1110 /* Clear brush with invalid mode. Unclear if this can still happen,
1111 * but kept from old paint tool-slots code. */
1112 Brush *brush = BKE_paint_brush(paint);
1113 if (brush && (paint->runtime.ob_mode & brush->ob_mode) == 0) {
1114 BKE_paint_brush_set(paint, nullptr);
1115 BKE_paint_brush_set_default(bmain, paint);
1116 }
1117
1118 Brush *eraser_brush = BKE_paint_eraser_brush(paint);
1119 if (eraser_brush && (paint->runtime.ob_mode & eraser_brush->ob_mode) == 0) {
1120 BKE_paint_eraser_brush_set(paint, nullptr);
1122 }
1123}
1124
1126{
1127 /* Don't resolve this during file read, it will be done after. */
1128 if (bmain->is_locked_for_linking) {
1129 return false;
1130 }
1131 /* Attempt to restore a valid active brush from brush asset information. */
1132 if (paint->eraser_brush != nullptr) {
1133 return false;
1134 }
1135 if (paint->eraser_brush_asset_reference == nullptr) {
1136 return false;
1137 }
1138
1139 Brush *brush = reinterpret_cast<Brush *>(blender::bke::asset_edit_id_from_weak_reference(
1140 *bmain, ID_BR, *paint->eraser_brush_asset_reference));
1141 BLI_assert(brush == nullptr || blender::bke::asset_edit_id_is_editable(brush->id));
1142
1143 /* Ensure we have a brush with appropriate mode to assign.
1144 * Could happen if contents of asset blend was manually changed. */
1145 if (brush == nullptr || (paint->runtime.ob_mode & brush->ob_mode) == 0) {
1146 MEM_delete(paint->eraser_brush_asset_reference);
1147 paint->eraser_brush_asset_reference = nullptr;
1148 return false;
1149 }
1150
1151 paint->eraser_brush = brush;
1152 return true;
1153}
1154
1156{
1157 return (Brush *)BKE_paint_eraser_brush_for_read((const Paint *)paint);
1158}
1159
1161{
1162 return paint ? paint->eraser_brush : nullptr;
1163}
1164
1166{
1167 if (paint == nullptr || paint->eraser_brush == brush) {
1168 return false;
1169 }
1170 if (brush && (paint->runtime.ob_mode & brush->ob_mode) == 0) {
1171 return false;
1172 }
1173
1174 paint->eraser_brush = brush;
1175
1176 MEM_delete(paint->eraser_brush_asset_reference);
1177 paint->eraser_brush_asset_reference = nullptr;
1178
1179 if (brush != nullptr) {
1180 std::optional<AssetWeakReference> weak_ref = blender::bke::asset_edit_weak_reference_from_id(
1181 brush->id);
1182 if (weak_ref.has_value()) {
1183 paint->eraser_brush_asset_reference = MEM_new<AssetWeakReference>(__func__, *weak_ref);
1184 }
1185 }
1186
1187 return true;
1188}
1189
1191{
1192 std::optional<AssetWeakReference> weak_ref = paint_brush_asset_reference_from_essentials(
1193 name, ob_mode);
1194 if (!weak_ref) {
1195 return {};
1196 }
1197
1198 return reinterpret_cast<Brush *>(
1200}
1201
1203{
1204 paint_brush_set_default_reference(paint, false, true);
1206}
1207
1208bool BKE_paint_eraser_brush_set_essentials(Main *bmain, Paint *paint, const char *name)
1209{
1212}
1213
1214static void paint_runtime_init(const ToolSettings *ts, Paint *paint)
1215{
1216 if (paint == &ts->imapaint.paint) {
1218 }
1219 else if (ts->sculpt && paint == &ts->sculpt->paint) {
1221 }
1222 else if (ts->vpaint && paint == &ts->vpaint->paint) {
1224 }
1225 else if (ts->wpaint && paint == &ts->wpaint->paint) {
1227 }
1228 else if (ts->gp_paint && paint == &ts->gp_paint->paint) {
1230 }
1231 else if (ts->gp_vertexpaint && paint == &ts->gp_vertexpaint->paint) {
1233 }
1234 else if (ts->gp_sculptpaint && paint == &ts->gp_sculptpaint->paint) {
1236 }
1237 else if (ts->gp_weightpaint && paint == &ts->gp_weightpaint->paint) {
1239 }
1240 else if (ts->curves_sculpt && paint == &ts->curves_sculpt->paint) {
1242 }
1243 else {
1245 }
1246
1247 paint->runtime.initialized = true;
1248}
1249
1251{
1252 switch (mode) {
1255 return offsetof(Brush, image_brush_type);
1256 case PaintMode::Sculpt:
1257 return offsetof(Brush, sculpt_brush_type);
1258 case PaintMode::Vertex:
1259 return offsetof(Brush, vertex_brush_type);
1260 case PaintMode::Weight:
1261 return offsetof(Brush, weight_brush_type);
1262 case PaintMode::GPencil:
1263 return offsetof(Brush, gpencil_brush_type);
1265 return offsetof(Brush, gpencil_vertex_brush_type);
1267 return offsetof(Brush, gpencil_sculpt_brush_type);
1269 return offsetof(Brush, gpencil_weight_brush_type);
1271 return offsetof(Brush, curves_sculpt_brush_type);
1273 return offsetof(Brush, gpencil_sculpt_brush_type);
1274 case PaintMode::Invalid:
1275 break; /* We don't use these yet. */
1276 }
1277 return 0;
1278}
1279
1280std::optional<int> BKE_paint_get_brush_type_from_obmode(const Brush *brush,
1281 const eObjectMode ob_mode)
1282{
1283 switch (ob_mode) {
1285 case OB_MODE_EDIT:
1286 return brush->image_brush_type;
1287 case OB_MODE_SCULPT:
1288 return brush->sculpt_brush_type;
1290 return brush->vertex_brush_type;
1292 return brush->weight_brush_type;
1294 return brush->gpencil_brush_type;
1296 return brush->gpencil_vertex_brush_type;
1298 return brush->gpencil_sculpt_brush_type;
1300 return brush->gpencil_weight_brush_type;
1302 return brush->curves_sculpt_brush_type;
1303 default:
1304 return {};
1305 }
1306}
1307
1308std::optional<int> BKE_paint_get_brush_type_from_paintmode(const Brush *brush,
1309 const PaintMode mode)
1310{
1311 switch (mode) {
1314 return brush->image_brush_type;
1315 case PaintMode::Sculpt:
1316 return brush->sculpt_brush_type;
1317 case PaintMode::Vertex:
1318 return brush->vertex_brush_type;
1319 case PaintMode::Weight:
1320 return brush->weight_brush_type;
1321 case PaintMode::GPencil:
1322 return brush->gpencil_brush_type;
1324 return brush->gpencil_vertex_brush_type;
1326 return brush->gpencil_sculpt_brush_type;
1328 return brush->gpencil_weight_brush_type;
1330 return brush->curves_sculpt_brush_type;
1332 return brush->gpencil_sculpt_brush_type;
1333 case PaintMode::Invalid:
1334 default:
1335 return {};
1336 }
1337}
1338
1339PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name)
1340{
1341 PaintCurve *pc = static_cast<PaintCurve *>(BKE_id_new(bmain, ID_PC, name));
1342 return pc;
1343}
1344
1346{
1347 return paint ? paint->palette : nullptr;
1348}
1349
1351{
1352 if (paint) {
1353 id_us_min((ID *)paint->palette);
1354 paint->palette = palette;
1355 id_us_plus((ID *)paint->palette);
1356 }
1357}
1358
1360{
1361 pc->add_index = (add_index || pc->tot_points == 1) ? (add_index + 1) : 0;
1362}
1363
1365{
1366 if (BLI_listbase_count_at_most(&palette->colors, palette->active_color) == palette->active_color)
1367 {
1368 palette->active_color--;
1369 }
1370
1371 BLI_remlink(&palette->colors, color);
1372
1373 if (palette->active_color < 0 && !BLI_listbase_is_empty(&palette->colors)) {
1374 palette->active_color = 0;
1375 }
1376
1377 MEM_freeN(color);
1378}
1379
1381{
1382 BLI_freelistN(&palette->colors);
1383 palette->active_color = 0;
1384}
1385
1386Palette *BKE_palette_add(Main *bmain, const char *name)
1387{
1388 Palette *palette = static_cast<Palette *>(BKE_id_new(bmain, ID_PAL, name));
1389 return palette;
1390}
1391
1393{
1394 PaletteColor *color = MEM_cnew<PaletteColor>(__func__);
1395 BLI_addtail(&palette->colors, color);
1396 return color;
1397}
1398
1399bool BKE_palette_is_empty(const Palette *palette)
1400{
1401 return BLI_listbase_is_empty(&palette->colors);
1402}
1403
1404/* helper function to sort using qsort */
1405static int palettecolor_compare_hsv(const void *a1, const void *a2)
1406{
1407 const tPaletteColorHSV *ps1 = static_cast<const tPaletteColorHSV *>(a1);
1408 const tPaletteColorHSV *ps2 = static_cast<const tPaletteColorHSV *>(a2);
1409
1410 /* Hue */
1411 if (ps1->h > ps2->h) {
1412 return 1;
1413 }
1414 if (ps1->h < ps2->h) {
1415 return -1;
1416 }
1417
1418 /* Saturation. */
1419 if (ps1->s > ps2->s) {
1420 return 1;
1421 }
1422 if (ps1->s < ps2->s) {
1423 return -1;
1424 }
1425
1426 /* Value. */
1427 if (1.0f - ps1->v > 1.0f - ps2->v) {
1428 return 1;
1429 }
1430 if (1.0f - ps1->v < 1.0f - ps2->v) {
1431 return -1;
1432 }
1433
1434 return 0;
1435}
1436
1437/* helper function to sort using qsort */
1438static int palettecolor_compare_svh(const void *a1, const void *a2)
1439{
1440 const tPaletteColorHSV *ps1 = static_cast<const tPaletteColorHSV *>(a1);
1441 const tPaletteColorHSV *ps2 = static_cast<const tPaletteColorHSV *>(a2);
1442
1443 /* Saturation. */
1444 if (ps1->s > ps2->s) {
1445 return 1;
1446 }
1447 if (ps1->s < ps2->s) {
1448 return -1;
1449 }
1450
1451 /* Value. */
1452 if (1.0f - ps1->v > 1.0f - ps2->v) {
1453 return 1;
1454 }
1455 if (1.0f - ps1->v < 1.0f - ps2->v) {
1456 return -1;
1457 }
1458
1459 /* Hue */
1460 if (ps1->h > ps2->h) {
1461 return 1;
1462 }
1463 if (ps1->h < ps2->h) {
1464 return -1;
1465 }
1466
1467 return 0;
1468}
1469
1470static int palettecolor_compare_vhs(const void *a1, const void *a2)
1471{
1472 const tPaletteColorHSV *ps1 = static_cast<const tPaletteColorHSV *>(a1);
1473 const tPaletteColorHSV *ps2 = static_cast<const tPaletteColorHSV *>(a2);
1474
1475 /* Value. */
1476 if (1.0f - ps1->v > 1.0f - ps2->v) {
1477 return 1;
1478 }
1479 if (1.0f - ps1->v < 1.0f - ps2->v) {
1480 return -1;
1481 }
1482
1483 /* Hue */
1484 if (ps1->h > ps2->h) {
1485 return 1;
1486 }
1487 if (ps1->h < ps2->h) {
1488 return -1;
1489 }
1490
1491 /* Saturation. */
1492 if (ps1->s > ps2->s) {
1493 return 1;
1494 }
1495 if (ps1->s < ps2->s) {
1496 return -1;
1497 }
1498
1499 return 0;
1500}
1501
1502static int palettecolor_compare_luminance(const void *a1, const void *a2)
1503{
1504 const tPaletteColorHSV *ps1 = static_cast<const tPaletteColorHSV *>(a1);
1505 const tPaletteColorHSV *ps2 = static_cast<const tPaletteColorHSV *>(a2);
1506
1507 float lumi1 = (ps1->rgb[0] + ps1->rgb[1] + ps1->rgb[2]) / 3.0f;
1508 float lumi2 = (ps2->rgb[0] + ps2->rgb[1] + ps2->rgb[2]) / 3.0f;
1509
1510 if (lumi1 > lumi2) {
1511 return -1;
1512 }
1513 if (lumi1 < lumi2) {
1514 return 1;
1515 }
1516
1517 return 0;
1518}
1519
1520void BKE_palette_sort_hsv(tPaletteColorHSV *color_array, const int totcol)
1521{
1522 /* Sort by Hue, Saturation and Value. */
1523 qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_hsv);
1524}
1525
1526void BKE_palette_sort_svh(tPaletteColorHSV *color_array, const int totcol)
1527{
1528 /* Sort by Saturation, Value and Hue. */
1529 qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_svh);
1530}
1531
1532void BKE_palette_sort_vhs(tPaletteColorHSV *color_array, const int totcol)
1533{
1534 /* Sort by Saturation, Value and Hue. */
1535 qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_vhs);
1536}
1537
1538void BKE_palette_sort_luminance(tPaletteColorHSV *color_array, const int totcol)
1539{
1540 /* Sort by Luminance (calculated with the average, enough for sorting). */
1541 qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_luminance);
1542}
1543
1544bool BKE_palette_from_hash(Main *bmain, GHash *color_table, const char *name, const bool linear)
1545{
1546 tPaletteColorHSV *color_array = nullptr;
1547 tPaletteColorHSV *col_elm = nullptr;
1548 bool done = false;
1549
1550 const int totpal = BLI_ghash_len(color_table);
1551
1552 if (totpal > 0) {
1553 color_array = static_cast<tPaletteColorHSV *>(
1554 MEM_calloc_arrayN(totpal, sizeof(tPaletteColorHSV), __func__));
1555 /* Put all colors in an array. */
1556 GHashIterator gh_iter;
1557 int t = 0;
1558 GHASH_ITER (gh_iter, color_table) {
1560 float r, g, b;
1561 float h, s, v;
1562 cpack_to_rgb(col, &r, &g, &b);
1563 rgb_to_hsv(r, g, b, &h, &s, &v);
1564
1565 col_elm = &color_array[t];
1566 col_elm->rgb[0] = r;
1567 col_elm->rgb[1] = g;
1568 col_elm->rgb[2] = b;
1569 col_elm->h = h;
1570 col_elm->s = s;
1571 col_elm->v = v;
1572 t++;
1573 }
1574 }
1575
1576 /* Create the Palette. */
1577 if (totpal > 0) {
1578 /* Sort by Hue and saturation. */
1579 BKE_palette_sort_hsv(color_array, totpal);
1580
1581 Palette *palette = BKE_palette_add(bmain, name);
1582 if (palette) {
1583 for (int i = 0; i < totpal; i++) {
1584 col_elm = &color_array[i];
1585 PaletteColor *palcol = BKE_palette_color_add(palette);
1586 if (palcol) {
1587 copy_v3_v3(palcol->rgb, col_elm->rgb);
1588 if (linear) {
1589 linearrgb_to_srgb_v3_v3(palcol->rgb, palcol->rgb);
1590 }
1591 }
1592 }
1593 done = true;
1594 }
1595 }
1596 else {
1597 done = false;
1598 }
1599
1600 if (totpal > 0) {
1601 MEM_SAFE_FREE(color_array);
1602 }
1603
1604 return done;
1605}
1606
1608{
1609 return ((ob != nullptr) && (ob->type == OB_MESH) && (ob->data != nullptr) &&
1610 (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) &&
1612}
1613
1615{
1616 return ((ob != nullptr) && (ob->type == OB_MESH) && (ob->data != nullptr) &&
1617 (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
1619}
1620
1622{
1623 if (ob == nullptr || ob->data == nullptr) {
1624 return false;
1625 }
1626 if (ob->type == OB_GREASE_PENCIL) {
1628 }
1629 return false;
1630}
1631
1637
1639{
1640 return ((ob != nullptr) && (ob->type == OB_MESH) && (ob->data != nullptr) &&
1642}
1643
1644void BKE_paint_cavity_curve_preset(Paint *paint, int preset)
1645{
1646 CurveMapping *cumap = nullptr;
1647 CurveMap *cuma = nullptr;
1648
1649 if (!paint->cavity_curve) {
1650 paint->cavity_curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
1651 }
1652 cumap = paint->cavity_curve;
1653 cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
1654 cumap->preset = preset;
1655
1656 cuma = cumap->cm;
1658 BKE_curvemapping_changed(cumap, false);
1659}
1660
1662{
1663 switch (mode) {
1664 case PaintMode::Sculpt:
1665 return OB_MODE_SCULPT;
1666 case PaintMode::Vertex:
1667 return OB_MODE_VERTEX_PAINT;
1668 case PaintMode::Weight:
1669 return OB_MODE_WEIGHT_PAINT;
1672 return OB_MODE_TEXTURE_PAINT;
1674 return OB_MODE_SCULPT_CURVES;
1675 case PaintMode::GPencil:
1679 case PaintMode::Invalid:
1680 default:
1681 return OB_MODE_OBJECT;
1682 }
1683}
1684
1686{
1687 Paint *paint = nullptr;
1688 if (*r_paint) {
1689 if (!(*r_paint)->runtime.initialized) {
1690 /* Currently only image painting is initialized this way, others have to be allocated. */
1691 BLI_assert(ELEM(*r_paint, (Paint *)&ts->imapaint));
1692
1693 paint_runtime_init(ts, *r_paint);
1694 }
1695 else {
1696 BLI_assert(ELEM(*r_paint,
1697 /* Cast is annoying, but prevent nullptr-pointer access. */
1698 (Paint *)ts->gp_paint,
1699 (Paint *)ts->gp_vertexpaint,
1700 (Paint *)ts->gp_sculptpaint,
1701 (Paint *)ts->gp_weightpaint,
1702 (Paint *)ts->sculpt,
1703 (Paint *)ts->vpaint,
1704 (Paint *)ts->wpaint,
1705 (Paint *)ts->curves_sculpt,
1706 (Paint *)&ts->imapaint));
1707#ifndef NDEBUG
1708 Paint paint_test = **r_paint;
1709 paint_runtime_init(ts, *r_paint);
1710 /* Swap so debug doesn't hide errors when release fails. */
1711 std::swap(**r_paint, paint_test);
1712 BLI_assert(paint_test.runtime.ob_mode == (*r_paint)->runtime.ob_mode);
1713#endif
1714 }
1715 return true;
1716 }
1717
1718 if (((VPaint **)r_paint == &ts->vpaint) || ((VPaint **)r_paint == &ts->wpaint)) {
1719 VPaint *data = MEM_cnew<VPaint>(__func__);
1720 paint = &data->paint;
1721 }
1722 else if ((Sculpt **)r_paint == &ts->sculpt) {
1723 Sculpt *data = MEM_cnew<Sculpt>(__func__);
1724
1726
1727 paint = &data->paint;
1728 }
1729 else if ((GpPaint **)r_paint == &ts->gp_paint) {
1730 GpPaint *data = MEM_cnew<GpPaint>(__func__);
1731 paint = &data->paint;
1732 }
1733 else if ((GpVertexPaint **)r_paint == &ts->gp_vertexpaint) {
1734 GpVertexPaint *data = MEM_cnew<GpVertexPaint>(__func__);
1735 paint = &data->paint;
1736 }
1737 else if ((GpSculptPaint **)r_paint == &ts->gp_sculptpaint) {
1738 GpSculptPaint *data = MEM_cnew<GpSculptPaint>(__func__);
1739 paint = &data->paint;
1740 }
1741 else if ((GpWeightPaint **)r_paint == &ts->gp_weightpaint) {
1742 GpWeightPaint *data = MEM_cnew<GpWeightPaint>(__func__);
1743 paint = &data->paint;
1744 }
1745 else if ((CurvesSculpt **)r_paint == &ts->curves_sculpt) {
1746 CurvesSculpt *data = MEM_cnew<CurvesSculpt>(__func__);
1747 paint = &data->paint;
1748 }
1749 else if (*r_paint == &ts->imapaint.paint) {
1750 paint = &ts->imapaint.paint;
1751 }
1752
1753 paint->flags |= PAINT_SHOW_BRUSH;
1754
1755 *r_paint = paint;
1756
1757 paint_runtime_init(ts, paint);
1758
1759 return false;
1760}
1761
1763{
1764 if (paint->brush_asset_reference) {
1766 }
1767 if (paint->eraser_brush_asset_reference) {
1769 }
1770
1771 if (!paint->brush) {
1772 BKE_paint_brush_set_default(bmain, paint);
1773 }
1774 if (!paint->eraser_brush) {
1776 }
1777}
1778
1780 Main *bmain, Scene *sce, PaintMode mode, const uchar col[3], const bool ensure_brushes)
1781{
1783
1785 Paint *paint = BKE_paint_get_active_from_paintmode(sce, mode);
1786
1787 if (ensure_brushes) {
1788 BKE_paint_brushes_ensure(bmain, paint);
1789 }
1790
1792 paint->paint_cursor_col[3] = 128;
1793 ups->last_stroke_valid = false;
1795 ups->average_stroke_counter = 0;
1796 if (!paint->cavity_curve) {
1798 }
1799}
1800
1802{
1804 MEM_delete(paint->brush_asset_reference);
1806 MEM_delete(paint->eraser_brush_asset_reference);
1807
1809 brush_ref,
1811 {
1812 MEM_delete(brush_ref->name);
1813 MEM_delete(brush_ref->brush_asset_reference);
1814 MEM_delete(brush_ref);
1815 }
1816}
1817
1818void BKE_paint_copy(const Paint *src, Paint *dst, const int flag)
1819{
1820 dst->brush = src->brush;
1822
1823 if (src->brush_asset_reference) {
1824 dst->brush_asset_reference = MEM_new<AssetWeakReference>(__func__,
1825 *src->brush_asset_reference);
1826 }
1828 dst->tool_brush_bindings.main_brush_asset_reference = MEM_new<AssetWeakReference>(
1830 }
1832 dst->eraser_brush_asset_reference = MEM_new<AssetWeakReference>(
1833 __func__, *src->eraser_brush_asset_reference);
1834 }
1839 {
1840 brush_ref->name = BLI_strdup(brush_ref->name);
1841 brush_ref->brush_asset_reference = MEM_new<AssetWeakReference>(
1842 __func__, *brush_ref->brush_asset_reference);
1843 }
1844
1845 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
1846 id_us_plus((ID *)dst->palette);
1847 }
1848}
1849
1850void BKE_paint_stroke_get_average(const Scene *scene, const Object *ob, float stroke[3])
1851{
1852 const UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
1853 if (ups->last_stroke_valid && ups->average_stroke_counter > 0) {
1854 float fac = 1.0f / ups->average_stroke_counter;
1855 mul_v3_v3fl(stroke, ups->average_stroke_accum, fac);
1856 }
1857 else {
1858 copy_v3_v3(stroke, ob->object_to_world().location());
1859 }
1860}
1861
1863{
1864 if (paint->cavity_curve) {
1866 }
1867 if (paint->brush_asset_reference) {
1869 }
1870 if (paint->eraser_brush_asset_reference) {
1872 }
1873
1874 {
1875 /* Write tool system bindings. */
1876 ToolSystemBrushBindings &tool_brush_bindings = paint->tool_brush_bindings;
1877
1878 if (tool_brush_bindings.main_brush_asset_reference) {
1880 }
1882 writer, NamedBrushAssetReference, &tool_brush_bindings.active_brush_per_brush_type);
1884 NamedBrushAssetReference *, brush_ref, &tool_brush_bindings.active_brush_per_brush_type)
1885 {
1886 BLO_write_string(writer, brush_ref->name);
1887 if (brush_ref->brush_asset_reference) {
1888 BKE_asset_weak_reference_write(writer, brush_ref->brush_asset_reference);
1889 }
1890 }
1891 }
1892}
1893
1894void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Paint *paint)
1895{
1896 BLO_read_struct(reader, CurveMapping, &paint->cavity_curve);
1897 if (paint->cavity_curve) {
1899 }
1900 else {
1902 }
1903
1905 if (paint->brush_asset_reference) {
1907 }
1909 if (paint->eraser_brush_asset_reference) {
1911 }
1912
1913 {
1914 /* Read tool system bindings. */
1915 ToolSystemBrushBindings &tool_brush_bindings = paint->tool_brush_bindings;
1916
1917 BLO_read_struct(reader, AssetWeakReference, &tool_brush_bindings.main_brush_asset_reference);
1918 if (tool_brush_bindings.main_brush_asset_reference) {
1919 BKE_asset_weak_reference_read(reader, tool_brush_bindings.main_brush_asset_reference);
1920 }
1921
1923 reader, NamedBrushAssetReference, &tool_brush_bindings.active_brush_per_brush_type);
1925 NamedBrushAssetReference *, brush_ref, &tool_brush_bindings.active_brush_per_brush_type)
1926 {
1927 BLO_read_string(reader, &brush_ref->name);
1928
1929 BLO_read_struct(reader, AssetWeakReference, &brush_ref->brush_asset_reference);
1930 if (brush_ref->brush_asset_reference) {
1931 BKE_asset_weak_reference_read(reader, brush_ref->brush_asset_reference);
1932 }
1933 }
1934 }
1935
1936 paint->paint_cursor = nullptr;
1937 paint_runtime_init(scene->toolsettings, paint);
1938}
1939
1941 const int gridsize,
1942 const int x,
1943 const int y)
1944{
1945 return grid_hidden[CCG_grid_xy_to_index(gridsize, x, y)] ||
1946 grid_hidden[CCG_grid_xy_to_index(gridsize, x + 1, y)] ||
1947 grid_hidden[CCG_grid_xy_to_index(gridsize, x + 1, y + 1)] ||
1948 grid_hidden[CCG_grid_xy_to_index(gridsize, x, y + 1)];
1949}
1950
1952{
1953 BMLoop *l_iter;
1954 BMLoop *l_first;
1955
1956 l_iter = l_first = BM_FACE_FIRST_LOOP(f);
1957 do {
1958 if (BM_elem_flag_test(l_iter->v, BM_ELEM_HIDDEN)) {
1959 return true;
1960 }
1961 } while ((l_iter = l_iter->next) != l_first);
1962
1963 return false;
1964}
1965
1966float paint_grid_paint_mask(const GridPaintMask *gpm, uint level, uint x, uint y)
1967{
1968 int factor = BKE_ccg_factor(level, gpm->level);
1969 int gridsize = BKE_ccg_gridsize(gpm->level);
1970
1971 return gpm->data[(y * factor) * gridsize + (x * factor)];
1972}
1973
1974/* Threshold to move before updating the brush rotation, reduces jitter. */
1975static float paint_rake_rotation_spacing(const UnifiedPaintSettings & /*ups*/, const Brush &brush)
1976{
1977 return brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_CLAY_STRIPS ? 1.0f : 20.0f;
1978}
1979
1981 const Brush &brush,
1982 float rotation)
1983{
1984 ups.brush_rotation = rotation;
1985
1987 ups.brush_rotation_sec = rotation;
1988 }
1989 else {
1990 ups.brush_rotation_sec = 0.0f;
1991 }
1992}
1993
1994static bool paint_rake_rotation_active(const MTex &mtex)
1995{
1996 return mtex.tex && mtex.brush_angle_mode & MTEX_ANGLE_RAKE;
1997}
1998
1999static const bool paint_rake_rotation_active(const Brush &brush, PaintMode paint_mode)
2000{
2002 BKE_brush_has_cube_tip(&brush, paint_mode);
2003}
2004
2006 const Brush &brush,
2007 const float mouse_pos[2],
2008 const PaintMode paint_mode,
2009 bool stroke_has_started)
2010{
2011 bool ok = false;
2012 if (paint_rake_rotation_active(brush, paint_mode)) {
2013 float r = paint_rake_rotation_spacing(ups, brush);
2014 float rotation;
2015
2016 /* Use a smaller limit if the stroke hasn't started to prevent excessive pre-roll. */
2017 if (!stroke_has_started) {
2018 r = min_ff(r, 4.0f);
2019 }
2020
2021 float dpos[2];
2022 sub_v2_v2v2(dpos, mouse_pos, ups.last_rake);
2023
2024 /* Limit how often we update the angle to prevent jitter. */
2025 if (len_squared_v2(dpos) >= r * r) {
2026 rotation = atan2f(dpos[1], dpos[0]) + float(0.5f * M_PI);
2027
2028 copy_v2_v2(ups.last_rake, mouse_pos);
2029
2030 ups.last_rake_angle = rotation;
2031
2032 paint_update_brush_rake_rotation(ups, brush, rotation);
2033 ok = true;
2034 }
2035 /* Make sure we reset here to the last rotation to avoid accumulating
2036 * values in case a random rotation is also added. */
2037 else {
2039 ok = false;
2040 }
2041 }
2042 else {
2043 ups.brush_rotation = ups.brush_rotation_sec = 0.0f;
2044 ok = true;
2045 }
2046 return ok;
2047}
2048
2050{
2051 ss->deform_cos = {};
2052 ss->deform_imats = {};
2053 ss->vert_normals_deform = {};
2054 ss->face_normals_deform = {};
2055}
2056
2068
2073{
2074 SculptSession &ss = *ob->sculpt;
2075
2076 if (ss.bm) {
2077 if (ob->data) {
2078 if (reorder) {
2080 }
2082 params.calc_object_remap = false;
2083 BM_mesh_bm_to_me(nullptr, ss.bm, static_cast<Mesh *>(ob->data), &params);
2084 }
2085 }
2086}
2087
2088void BKE_sculptsession_bm_to_me(Object *ob, bool reorder)
2089{
2090 if (ob && ob->sculpt) {
2092
2093 /* Ensure the objects evaluated mesh doesn't hold onto arrays
2094 * now realloc'd in the mesh #34473. */
2096 }
2097}
2098
2100{
2101 SculptSession *ss = object.sculpt;
2102 if (!ss) {
2103 return;
2104 }
2105
2106 ss->pbvh.reset();
2107 ss->edge_to_face_offsets = {};
2108 ss->edge_to_face_indices = {};
2109 ss->edge_to_face_map = {};
2110 ss->vert_to_edge_offsets = {};
2111 ss->vert_to_edge_indices = {};
2112 ss->vert_to_edge_map = {};
2113
2114 ss->preview_verts = {};
2115
2118 ss->topology_island_cache.reset();
2119
2120 ss->clear_active_vert(false);
2121}
2122
2124{
2125 if (object && object->sculpt) {
2126 if (object->sculpt->bm) {
2127 /* Ensure no points to old arrays are stored in DM
2128 *
2129 * Apparently, we could not use DEG_id_tag_update
2130 * here because this will lead to the while object
2131 * surface to disappear, so we'll release DM in place.
2132 */
2134
2136
2137 /* In contrast with sculptsession_bm_to_me no need in
2138 * DAG tag update here - derived mesh was freed and
2139 * old pointers are nowhere stored.
2140 */
2141 }
2142 }
2143}
2144
2146{
2147 if (ob && ob->sculpt) {
2148 SculptSession *ss = ob->sculpt;
2149
2150 if (ss->bm) {
2152 BM_mesh_free(ss->bm);
2153 }
2154
2156
2157 MEM_delete(ss);
2158
2159 ob->sculpt = nullptr;
2160 }
2161}
2162
2164
2166{
2167 if (this->bm_log) {
2168 BM_log_free(this->bm_log);
2169 }
2170
2171 if (this->tex_pool) {
2173 }
2174
2176
2178}
2179
2181{
2182 return active_vert_;
2183}
2184
2186{
2187 return active_vert_;
2188}
2189
2191{
2192 if (std::holds_alternative<int>(active_vert_)) {
2193 return std::get<int>(active_vert_);
2194 }
2195 if (std::holds_alternative<SubdivCCGCoord>(active_vert_)) {
2196 const SubdivCCGCoord coord = std::get<SubdivCCGCoord>(active_vert_);
2197 return coord.to_index(BKE_subdiv_ccg_key_top_level(*this->subdiv_ccg));
2198 }
2199 if (std::holds_alternative<BMVert *>(active_vert_)) {
2200 BMVert *bm_vert = std::get<BMVert *>(active_vert_);
2201 return BM_elem_index_get(bm_vert);
2202 }
2203
2204 return -1;
2205}
2206
2208{
2209 if (std::holds_alternative<int>(last_active_vert_)) {
2210 return std::get<int>(last_active_vert_);
2211 }
2212 if (std::holds_alternative<SubdivCCGCoord>(last_active_vert_)) {
2213 const SubdivCCGCoord coord = std::get<SubdivCCGCoord>(last_active_vert_);
2214 return coord.to_index(BKE_subdiv_ccg_key_top_level(*this->subdiv_ccg));
2215 }
2216 if (std::holds_alternative<BMVert *>(last_active_vert_)) {
2217 BMVert *bm_vert = std::get<BMVert *>(last_active_vert_);
2218 return BM_elem_index_get(bm_vert);
2219 }
2220
2221 return -1;
2222}
2223
2225 const Object &object) const
2226{
2227 if (std::holds_alternative<int>(active_vert_)) {
2229 return positions[std::get<int>(active_vert_)];
2230 }
2231 if (std::holds_alternative<SubdivCCGCoord>(active_vert_)) {
2233 const SubdivCCGCoord coord = std::get<SubdivCCGCoord>(active_vert_);
2234 return this->subdiv_ccg->positions[coord.to_index(key)];
2235 }
2236 if (std::holds_alternative<BMVert *>(active_vert_)) {
2237 BMVert *bm_vert = std::get<BMVert *>(active_vert_);
2238 return bm_vert->co;
2239 }
2240
2242 return float3(std::numeric_limits<float>::infinity());
2243}
2244
2245void SculptSession::clear_active_vert(bool persist_last_active)
2246{
2247 if (persist_last_active) {
2248 if (!std::holds_alternative<std::monostate>(active_vert_)) {
2249 last_active_vert_ = active_vert_;
2250 }
2251 }
2252 else {
2253 last_active_vert_ = {};
2254 }
2255 active_vert_ = {};
2256}
2257
2259{
2260 active_vert_ = vert;
2261}
2262
2264 Object *ob,
2265 const bool auto_create_mdisps)
2266{
2267 Mesh *mesh = (Mesh *)ob->data;
2268 ModifierData *md;
2269 VirtualModifierData virtual_modifier_data;
2270
2271 if (ob->sculpt && ob->sculpt->bm) {
2272 /* Can't combine multires and dynamic topology. */
2273 return nullptr;
2274 }
2275
2276 bool need_mdisps = false;
2277
2278 if (!CustomData_get_layer(&mesh->corner_data, CD_MDISPS)) {
2279 if (!auto_create_mdisps) {
2280 /* Multires can't work without displacement layer. */
2281 return nullptr;
2282 }
2283 need_mdisps = true;
2284 }
2285
2286 /* Weight paint operates on original vertices, and needs to treat multires as regular modifier
2287 * to make it so that pbvh::Tree vertices are at the multires surface. */
2288 if ((ob->mode & OB_MODE_SCULPT) == 0) {
2289 return nullptr;
2290 }
2291
2292 for (md = BKE_modifiers_get_virtual_modifierlist(ob, &virtual_modifier_data); md; md = md->next)
2293 {
2294 if (md->type == eModifierType_Multires) {
2296
2298 continue;
2299 }
2300
2301 if (mmd->sculptlvl > 0 && !(mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh)) {
2302 if (need_mdisps) {
2303 CustomData_add_layer(&mesh->corner_data, CD_MDISPS, CD_SET_DEFAULT, mesh->corners_num);
2304 }
2305
2306 return mmd;
2307 }
2308
2309 return nullptr;
2310 }
2311 }
2312
2313 return nullptr;
2314}
2315
2317{
2318 return sculpt_multires_modifier_get(scene, ob, false);
2319}
2320
2321/* Checks if there are any supported deformation modifiers active */
2322static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
2323{
2324 ModifierData *md;
2325 Mesh *mesh = (Mesh *)ob->data;
2326 VirtualModifierData virtual_modifier_data;
2327
2328 if (ob->sculpt->bm || BKE_sculpt_multires_active(scene, ob)) {
2329 return false;
2330 }
2331
2332 /* Non-locked shape keys could be handled in the same way as deformed mesh. */
2333 if ((ob->shapeflag & OB_SHAPE_LOCK) == 0 && mesh->key && ob->shapenr) {
2334 return true;
2335 }
2336
2337 md = BKE_modifiers_get_virtual_modifierlist(ob, &virtual_modifier_data);
2338
2339 /* Exception for shape keys because we can edit those. */
2340 for (; md; md = md->next) {
2341 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
2343 continue;
2344 }
2345 if (md->type == eModifierType_Multires && (ob->mode & OB_MODE_SCULPT)) {
2348 continue;
2349 }
2350 }
2351 if (md->type == eModifierType_ShapeKey) {
2352 continue;
2353 }
2354
2355 if (mti->type == ModifierTypeType::OnlyDeform) {
2356 return true;
2357 }
2358 if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) {
2359 return true;
2360 }
2361 }
2362
2363 return false;
2364}
2365
2366static void sculpt_update_object(Depsgraph *depsgraph,
2367 Object *ob,
2368 Object *ob_eval,
2369 bool is_paint_tool)
2370{
2371 using namespace blender;
2372 using namespace blender::bke;
2374 Sculpt *sd = scene->toolsettings->sculpt;
2375 SculptSession &ss = *ob->sculpt;
2376 Mesh *mesh_orig = BKE_object_get_original_mesh(ob);
2377 /* Use the "unchecked" function, because this code also runs as part of the depsgraph node that
2378 * evaluates the object's geometry. So from perspective of the depsgraph, the mesh is not fully
2379 * evaluated yet. */
2380 Mesh *mesh_eval = BKE_object_get_evaluated_mesh_unchecked(ob_eval);
2381 MultiresModifierData *mmd = sculpt_multires_modifier_get(scene, ob, true);
2382
2383 BLI_assert(mesh_eval != nullptr);
2384
2385 /* This is for handling a newly opened file with no object visible,
2386 * causing `mesh_eval == nullptr`. */
2387 if (mesh_eval == nullptr) {
2388 return;
2389 }
2390
2392
2393 ss.building_vp_handle = false;
2394
2395 ss.shapekey_active = (mmd == nullptr) ? BKE_keyblock_from_object(ob) : nullptr;
2396
2397 /* NOTE: Weight pPaint require mesh info for loop lookup, but it never uses multires code path,
2398 * so no extra checks is needed here. */
2399 if (mmd) {
2400 ss.multires.active = true;
2401 ss.multires.modifier = mmd;
2402 ss.multires.level = mmd->sculptlvl;
2403 }
2404 else {
2405 ss.multires.active = false;
2406 ss.multires.modifier = nullptr;
2407 ss.multires.level = 0;
2408 }
2409
2410 ss.subdiv_ccg = mesh_eval->runtime->subdiv_ccg.get();
2411
2412 pbvh::Tree &pbvh = object::pbvh_ensure(*depsgraph, *ob);
2413
2414 if (ss.deform_modifiers_active) {
2415 /* Painting doesn't need crazyspace, use already evaluated mesh coordinates if possible. */
2416 bool used_me_eval = false;
2417
2419 const Mesh *me_eval_deform = BKE_object_get_mesh_deform_eval(ob_eval);
2420
2421 /* If the fully evaluated mesh has the same topology as the deform-only version, use it.
2422 * This matters because crazyspace evaluation is very restrictive and excludes even modifiers
2423 * that simply recompute vertex weights (which can even include Geometry Nodes). */
2424 if (me_eval_deform->faces_num == mesh_eval->faces_num &&
2425 me_eval_deform->corners_num == mesh_eval->corners_num &&
2426 me_eval_deform->verts_num == mesh_eval->verts_num)
2427 {
2429
2430 BLI_assert(me_eval_deform->verts_num == mesh_orig->verts_num);
2431
2432 ss.deform_cos = mesh_eval->vert_positions();
2434
2435 used_me_eval = true;
2436 }
2437 }
2438
2439 /* We depend on the deform coordinates not being updated in the middle of a stroke. This array
2440 * eventually gets cleared inside BKE_sculpt_update_object_before_eval.
2441 * See #126713 for more information. */
2442 if (ss.deform_cos.is_empty() && !used_me_eval) {
2444
2447
2448 for (blender::float3x3 &matrix : ss.deform_imats) {
2449 matrix = blender::math::invert(matrix);
2450 }
2451 }
2452 }
2453 else {
2455 }
2456
2457 if (ss.shapekey_active != nullptr && ss.deform_cos.is_empty()) {
2458 ss.deform_cos = Span(static_cast<const float3 *>(ss.shapekey_active->data),
2459 mesh_orig->verts_num);
2460 }
2461
2462 /* if pbvh is deformed, key block is already applied to it */
2463 if (ss.shapekey_active) {
2464 if (ss.deform_cos.is_empty()) {
2465 const Span key_data(static_cast<const float3 *>(ss.shapekey_active->data),
2466 mesh_orig->verts_num);
2467
2468 if (key_data.data() != nullptr) {
2469 BKE_pbvh_vert_coords_apply(pbvh, key_data);
2470 if (ss.deform_cos.is_empty()) {
2471 ss.deform_cos = key_data;
2472 }
2473 }
2474 }
2475 }
2476
2477 if (is_paint_tool) {
2478 /* We should rebuild the PBVH_pixels when painting canvas changes.
2479 *
2480 * The relevant changes are stored/encoded in the paint canvas key.
2481 * These include the active uv map, and resolutions. */
2482 if (U.experimental.use_sculpt_texture_paint) {
2483 char *paint_canvas_key = BKE_paint_canvas_key_get(&scene->toolsettings->paint_mode, ob);
2484 if (ss.last_paint_canvas_key == nullptr ||
2485 !STREQ(paint_canvas_key, ss.last_paint_canvas_key))
2486 {
2488 ss.last_paint_canvas_key = paint_canvas_key;
2490 }
2491 else {
2492 MEM_freeN(paint_canvas_key);
2493 }
2494 }
2495
2496 /* We could be more precise when we have access to the active tool. */
2497 const bool use_paint_slots = (ob->mode & OB_MODE_SCULPT) != 0;
2498 if (use_paint_slots) {
2500 }
2501 }
2502
2503 /* This solves a crash when running a sculpt brush in background mode, because there is no redraw
2504 * after entering sculpt mode to make sure normals are allocated. Recalculating normals with
2505 * every brush step is too expensive currently. */
2506 bke::pbvh::update_normals(*depsgraph, *ob, pbvh);
2507}
2508
2510{
2511 using namespace blender;
2512 /* Update before mesh evaluation in the dependency graph. */
2513 Object *ob_orig = DEG_get_original_object(ob_eval);
2514 SculptSession *ss = ob_orig->sculpt;
2515 if (!ss) {
2516 return;
2517 }
2518 if (ss->building_vp_handle) {
2519 return;
2520 }
2521
2522 bke::pbvh::Tree *pbvh = bke::object::pbvh_get(*ob_orig);
2523
2524 if (!ss->cache && !ss->filter_cache && !ss->expand_cache) {
2525 /* Avoid performing the following normal update for Multires, as it causes race conditions
2526 * and other intermittent crashes with shared meshes.
2527 * See !125268 and #125157 for more information. */
2528 if (pbvh && pbvh->type() != blender::bke::pbvh::Type::Grids) {
2529 /* pbvh::Tree nodes may contain dirty normal tags. To avoid losing that information when
2530 * the pbvh::Tree is deleted, make sure all tagged geometry normals are up to date.
2531 * See #122947 for more information. */
2533 }
2534 /* We free pbvh on changes, except in the middle of drawing a stroke
2535 * since it can't deal with changing PVBH node organization, we hope
2536 * topology does not change in the meantime .. weak. */
2538
2540
2541 /* In vertex/weight paint, force maps to be rebuilt. */
2543 }
2544 else if (pbvh) {
2545 IndexMaskMemory memory;
2546 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(*pbvh, memory);
2547 pbvh->tag_positions_changed(node_mask);
2548 switch (pbvh->type()) {
2549 case bke::pbvh::Type::Mesh: {
2551 node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update(nodes[i]); });
2552 break;
2553 }
2554 case bke::pbvh::Type::Grids: {
2556 node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update(nodes[i]); });
2557 break;
2558 }
2559 case bke::pbvh::Type::BMesh: {
2561 node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update(nodes[i]); });
2562 break;
2563 }
2564 }
2565 }
2566}
2567
2569{
2570 /* Update after mesh evaluation in the dependency graph, to rebuild pbvh::Tree or
2571 * other data when modifiers change the mesh. */
2572 Object *ob_orig = DEG_get_original_object(ob_eval);
2573
2574 sculpt_update_object(depsgraph, ob_orig, ob_eval, false);
2575}
2576
2578{
2579 using namespace blender;
2580 using namespace blender::bke;
2581 Mesh *orig_me = BKE_object_get_original_mesh(object);
2582
2583 if (BKE_color_attribute_supported(*orig_me, orig_me->active_color_attribute)) {
2584 return;
2585 }
2586
2587 AttributeOwner owner = AttributeOwner::from_id(&orig_me->id);
2588 const std::string unique_name = BKE_attribute_calc_unique_name(owner, "Color");
2589 if (!orig_me->attributes_for_write().add(
2590 unique_name, AttrDomain::Point, CD_PROP_COLOR, AttributeInitDefaultValue()))
2591 {
2592 return;
2593 }
2594
2598 BKE_mesh_tessface_clear(orig_me);
2599}
2600
2601void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bool is_paint_tool)
2602{
2603 BLI_assert(ob_orig == DEG_get_original_object(ob_orig));
2604
2605 Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_orig);
2606
2607 sculpt_update_object(depsgraph, ob_orig, ob_eval, is_paint_tool);
2608}
2609
2611 Main *bmain,
2612 Object *ob,
2614{
2615 using namespace blender;
2616 using namespace blender::bke;
2617 Mesh *mesh = static_cast<Mesh *>(ob->data);
2618 const OffsetIndices faces = mesh->faces();
2619 const Span<int> corner_verts = mesh->corner_verts();
2620 MutableAttributeAccessor attributes = mesh->attributes_for_write();
2621
2622 /* if multires is active, create a grid paint mask layer if there
2623 * isn't one already */
2624 if (mmd && !CustomData_has_layer(&mesh->corner_data, CD_GRID_PAINT_MASK)) {
2625 int level = max_ii(1, mmd->sculptlvl);
2626 int gridsize = BKE_ccg_gridsize(level);
2627 int gridarea = gridsize * gridsize;
2628
2629 GridPaintMask *gmask = static_cast<GridPaintMask *>(CustomData_add_layer(
2630 &mesh->corner_data, CD_GRID_PAINT_MASK, CD_SET_DEFAULT, mesh->corners_num));
2631
2632 for (int i = 0; i < mesh->corners_num; i++) {
2633 GridPaintMask *gpm = &gmask[i];
2634
2635 gpm->level = level;
2636 gpm->data = static_cast<float *>(
2637 MEM_callocN(sizeof(float) * gridarea, "GridPaintMask.data"));
2638 }
2639
2640 /* If vertices already have mask, copy into multires data. */
2641 if (const VArray<float> mask = *attributes.lookup<float>(".sculpt_mask", AttrDomain::Point)) {
2642 const VArraySpan<float> mask_span(mask);
2643 for (const int i : faces.index_range()) {
2644 const IndexRange face = faces[i];
2645
2646 /* Mask center. */
2647 float avg = 0.0f;
2648 for (const int vert : corner_verts.slice(face)) {
2649 avg += mask_span[vert];
2650 }
2651 avg /= float(face.size());
2652
2653 /* Fill in multires mask corner. */
2654 for (const int corner : face) {
2655 GridPaintMask *gpm = &gmask[corner];
2656 const int vert = corner_verts[corner];
2657 const int prev = corner_verts[mesh::face_corner_prev(face, corner)];
2658 const int next = corner_verts[mesh::face_corner_next(face, corner)];
2659
2660 gpm->data[0] = avg;
2661 gpm->data[1] = (mask_span[vert] + mask_span[next]) * 0.5f;
2662 gpm->data[2] = (mask_span[vert] + mask_span[prev]) * 0.5f;
2663 gpm->data[3] = mask_span[vert];
2664 }
2665 }
2666 }
2667 /* The evaluated multires CCG must be updated to contain the new data. */
2669 if (depsgraph) {
2671 }
2672 }
2673 else {
2674 attributes.add<float>(".sculpt_mask", AttrDomain::Point, AttributeInitDefaultValue());
2675 }
2676}
2677
2679{
2680 BKE_paint_ensure(scene->toolsettings, (Paint **)&scene->toolsettings->sculpt);
2681 BKE_paint_brushes_ensure(bmain, &scene->toolsettings->sculpt->paint);
2682
2683 Sculpt *sd = scene->toolsettings->sculpt;
2684
2685 const Sculpt *defaults = DNA_struct_default_get(Sculpt);
2686
2687 /* We have file versioning code here for historical
2688 * reasons. Don't add more checks here, do it properly
2689 * in blenloader.
2690 */
2691 if (sd->automasking_start_normal_limit == 0.0f) {
2694
2697 }
2698
2699 if (sd->detail_percent == 0.0f) {
2700 sd->detail_percent = defaults->detail_percent;
2701 }
2702 if (sd->constant_detail == 0.0f) {
2703 sd->constant_detail = defaults->constant_detail;
2704 }
2705 if (sd->detail_size == 0.0f) {
2706 sd->detail_size = defaults->detail_size;
2707 }
2708
2709 /* Set sane default tiling offsets. */
2710 if (!sd->paint.tile_offset[0]) {
2711 sd->paint.tile_offset[0] = 1.0f;
2712 }
2713 if (!sd->paint.tile_offset[1]) {
2714 sd->paint.tile_offset[1] = 1.0f;
2715 }
2716 if (!sd->paint.tile_offset[2]) {
2717 sd->paint.tile_offset[2] = 1.0f;
2718 }
2719
2722 }
2723}
2724
2725static bool check_sculpt_object_deformed(Object *object, const bool for_construction)
2726{
2727 bool deformed = false;
2728
2729 /* Active modifiers means extra deformation, which can't be handled correct
2730 * on birth of pbvh::Tree and sculpt "layer" levels, so use pbvh::Tree only for internal brush
2731 * stuff and show final evaluated mesh so user would see actual object shape. */
2732 deformed |= object->sculpt->deform_modifiers_active;
2733
2734 if (for_construction) {
2735 deformed |= object->sculpt->shapekey_active != nullptr;
2736 }
2737 else {
2738 /* As in case with modifiers, we can't synchronize deformation made against
2739 * pbvh::Tree and non-locked keyblock, so also use pbvh::Tree only for brushes and
2740 * final DM to give final result to user. */
2741 deformed |= object->sculpt->shapekey_active && (object->shapeflag & OB_SHAPE_LOCK) == 0;
2742 }
2743
2744 return deformed;
2745}
2746
2748{
2749 using namespace blender;
2750 using namespace blender::bke;
2751
2752 const AttributeAccessor attributes = mesh.attributes();
2753 const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
2754 ".hide_poly", AttrDomain::Face, false);
2755 if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
2757 return;
2758 }
2759
2760 const OffsetIndices<int> faces = mesh.faces();
2761
2762 const VArraySpan<bool> hide_poly_span(hide_poly);
2763 BitGroupVector<> &grid_hidden = BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg);
2764 threading::parallel_for(faces.index_range(), 1024, [&](const IndexRange range) {
2765 for (const int i : range) {
2766 const bool face_hidden = hide_poly_span[i];
2767 for (const int corner : faces[i]) {
2768 grid_hidden[corner].set_all(face_hidden);
2769 }
2770 }
2771 });
2772}
2773
2774namespace blender::bke {
2775
2776static std::unique_ptr<pbvh::Tree> build_pbvh_for_dynamic_topology(Object *ob)
2777{
2778 BMesh &bm = *ob->sculpt->bm;
2779 BM_data_layer_ensure_named(&bm, &bm.vdata, CD_PROP_INT32, ".sculpt_dyntopo_node_id_vertex");
2780 BM_data_layer_ensure_named(&bm, &bm.pdata, CD_PROP_INT32, ".sculpt_dyntopo_node_id_face");
2781
2782 return std::make_unique<pbvh::Tree>(pbvh::Tree::from_bmesh(bm));
2783}
2784
2785static std::unique_ptr<pbvh::Tree> build_pbvh_from_regular_mesh(Object *ob,
2786 const Mesh *me_eval_deform)
2787{
2788 const Mesh &mesh = *BKE_object_get_original_mesh(ob);
2789 std::unique_ptr<pbvh::Tree> pbvh = std::make_unique<pbvh::Tree>(pbvh::Tree::from_mesh(mesh));
2790
2791 const bool is_deformed = check_sculpt_object_deformed(ob, true);
2792 if (is_deformed && me_eval_deform != nullptr) {
2793 BKE_pbvh_vert_coords_apply(*pbvh, me_eval_deform->vert_positions());
2794 }
2795
2796 return pbvh;
2797}
2798
2799static std::unique_ptr<pbvh::Tree> build_pbvh_from_ccg(Object *ob, SubdivCCG &subdiv_ccg)
2800{
2801 const Mesh &base_mesh = *BKE_mesh_from_object(ob);
2802 BKE_sculpt_sync_face_visibility_to_grids(base_mesh, subdiv_ccg);
2803
2804 return std::make_unique<pbvh::Tree>(pbvh::Tree::from_grids(base_mesh, subdiv_ccg));
2805}
2806
2807} // namespace blender::bke
2808
2809namespace blender::bke::object {
2810
2812{
2813 if (pbvh::Tree *pbvh = pbvh_get(object)) {
2814 return *pbvh;
2815 }
2816 BLI_assert(object.sculpt != nullptr);
2817 SculptSession &ss = *object.sculpt;
2818
2819 if (ss.bm != nullptr) {
2820 /* Sculpting on a BMesh (dynamic-topology) gets a special pbvh::Tree. */
2822 }
2823 else {
2824 Object *object_eval = DEG_get_evaluated_object(&depsgraph, &object);
2825 Mesh *mesh_eval = static_cast<Mesh *>(object_eval->data);
2826 if (mesh_eval->runtime->subdiv_ccg != nullptr) {
2827 ss.pbvh = build_pbvh_from_ccg(&object, *mesh_eval->runtime->subdiv_ccg);
2828 }
2829 else {
2830 const Mesh *me_eval_deform = BKE_object_get_mesh_deform_eval(object_eval);
2831 ss.pbvh = build_pbvh_from_regular_mesh(&object, me_eval_deform);
2832 }
2833 }
2834
2835 return *object::pbvh_get(object);
2836}
2837
2838const pbvh::Tree *pbvh_get(const Object &object)
2839{
2840 if (!object.sculpt) {
2841 return nullptr;
2842 }
2843 return object.sculpt->pbvh.get();
2844}
2845
2847{
2848 BLI_assert(object.type == OB_MESH);
2849 if (!object.sculpt) {
2850 return nullptr;
2851 }
2852 return object.sculpt->pbvh.get();
2853}
2854
2855} // namespace blender::bke::object
2856
2858{
2859 return object->sculpt && object->sculpt->bm;
2860}
2861
2863{
2864 SculptSession *ss = ob->sculpt;
2865 if (ss == nullptr || ss->mode_type != OB_MODE_SCULPT) {
2866 return false;
2867 }
2869 if (!pbvh) {
2870 return false;
2871 }
2872
2873 if (pbvh->type() == blender::bke::pbvh::Type::Mesh) {
2874 /* Regular mesh only draws from pbvh::Tree without modifiers and shape keys, or for
2875 * external engines that do not have access to the pbvh::Tree like Eevee does. */
2876 const bool external_engine = rv3d && rv3d->view_render != nullptr;
2877 return !(ss->shapekey_active || ss->deform_modifiers_active || external_engine);
2878 }
2879
2880 /* Multires and dyntopo always draw directly from the pbvh::Tree. */
2881 return true;
2882}
2883
2884/* Returns the Face Set random color for rendering in the overlay given its ID and a color seed. */
2885#define GOLDEN_RATIO_CONJUGATE 0.618033988749895f
2886void BKE_paint_face_set_overlay_color_get(const int face_set, const int seed, uchar r_color[4])
2887{
2888 float rgba[4];
2889 float random_mod_hue = GOLDEN_RATIO_CONJUGATE * (face_set + (seed % 10));
2890 random_mod_hue = random_mod_hue - floorf(random_mod_hue);
2891 const float random_mod_sat = BLI_hash_int_01(face_set + seed + 1);
2892 const float random_mod_val = BLI_hash_int_01(face_set + seed + 2);
2893 hsv_to_rgb(random_mod_hue,
2894 0.6f + (random_mod_sat * 0.25f),
2895 1.0f - (random_mod_val * 0.35f),
2896 &rgba[0],
2897 &rgba[1],
2898 &rgba[2]);
2899 rgba_float_to_uchar(r_color, rgba);
2900}
void BKE_asset_weak_reference_read(BlendDataReader *reader, AssetWeakReference *weak_ref)
void BKE_asset_weak_reference_write(BlendWriter *writer, const AssetWeakReference *weak_ref)
void BKE_id_attributes_default_color_set(struct ID *id, const char *name)
Definition attribute.cc:994
void BKE_id_attributes_active_color_set(struct ID *id, const char *name)
Definition attribute.cc:965
std::string BKE_attribute_calc_unique_name(const AttributeOwner &owner, const blender::StringRef name)
Definition attribute.cc:359
bool BKE_color_attribute_supported(const struct Mesh &mesh, const blender::StringRef name)
bool BKE_brush_has_cube_tip(const Brush *brush, PaintMode paint_mode)
Definition brush.cc:1514
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
Definition BKE_ccg.hh:77
@ CURVEMAP_SLOPE_POSITIVE
void BKE_curvemapping_blend_read(BlendDataReader *reader, CurveMapping *cumap)
CurveMapping * BKE_curvemapping_copy(const CurveMapping *cumap)
CurveMapping * BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
Definition colortools.cc:90
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)
SpaceImage * CTX_wm_space_image(const bContext *C)
@ CTX_MODE_VERTEX_GPENCIL_LEGACY
@ CTX_MODE_WEIGHT_GPENCIL_LEGACY
@ CTX_MODE_SCULPT_GPENCIL_LEGACY
@ CTX_MODE_PAINT_GREASE_PENCIL
@ CTX_MODE_PAINT_GPENCIL_LEGACY
@ CTX_MODE_PAINT_TEXTURE
@ CTX_MODE_SCULPT_GREASE_PENCIL
@ CTX_MODE_SCULPT
@ CTX_MODE_SCULPT_CURVES
@ CTX_MODE_WEIGHT_GREASE_PENCIL
@ CTX_MODE_VERTEX_GREASE_PENCIL
@ CTX_MODE_PAINT_VERTEX
@ CTX_MODE_PAINT_WEIGHT
Scene * CTX_data_scene(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
void BKE_crazyspace_build_sculpt(Depsgraph *depsgraph, Scene *scene, Object *ob, blender::Array< blender::float3x3, 0 > &deformmats, blender::Array< blender::float3, 0 > &deformcos)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
@ CD_SET_DEFAULT
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
support for deformation groups and hooks.
void BKE_defvert_array_free_elems(MDeformVert *dvert, int totvert)
Definition deform.cc:1048
@ IDTYPE_FLAGS_NO_ANIMDATA
Definition BKE_idtype.hh:41
void BKE_image_pool_free(ImagePool *pool)
KeyBlock * BKE_keyblock_from_object(Object *ob)
Definition key.cc:1905
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
@ LIB_ID_CREATE_NO_USER_REFCOUNT
void id_us_plus(ID *id)
Definition lib_id.cc:351
void id_fake_user_set(ID *id)
Definition lib_id.cc:389
void BKE_lib_id_swap(Main *bmain, ID *id_a, ID *id_b, const bool do_self_remap, const int self_remap_flags)
Definition lib_id.cc:1022
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1482
void id_us_min(ID *id)
Definition lib_id.cc:359
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition lib_id.cc:2560
General operations, lookup, etc. for materials.
void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob)
void BKE_mesh_tessface_clear(Mesh *mesh)
Mesh * BKE_mesh_from_object(Object *ob)
bool BKE_modifier_is_enabled(const Scene *scene, ModifierData *md, int required_mode)
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_mesh_deform_eval(const Object *object)
Mesh * BKE_object_get_evaluated_mesh_unchecked(const Object *object)
Mesh * BKE_object_get_original_mesh(const Object *object)
void BKE_object_free_derived_caches(Object *ob)
void BKE_sculpt_sync_face_visibility_to_grids(const Mesh &mesh, SubdivCCG &subdiv_ccg)
Definition paint.cc:2747
PaintMode
Definition BKE_paint.hh:99
@ SculptGreasePencil
std::variant< std::monostate, int, SubdivCCGCoord, BMVert * > ActiveVert
Definition BKE_paint.hh:377
void BKE_sculptsession_free_vwpaint_data(SculptSession *ss)
Definition paint.cc:2057
ePaintOverlayControlFlags
Definition BKE_paint.hh:123
@ PAINT_OVERLAY_INVALID_CURVE
Definition BKE_paint.hh:126
@ PAINT_OVERLAY_INVALID_TEXTURE_SECONDARY
Definition BKE_paint.hh:125
@ PAINT_OVERLAY_OVERRIDE_CURSOR
Definition BKE_paint.hh:127
@ PAINT_OVERLAY_INVALID_TEXTURE_PRIMARY
Definition BKE_paint.hh:124
@ PAINT_OVERLAY_OVERRIDE_SECONDARY
Definition BKE_paint.hh:129
@ PAINT_OVERLAY_OVERRIDE_PRIMARY
Definition BKE_paint.hh:128
#define PAINT_OVERRIDE_MASK
Definition BKE_paint.hh:133
void BKE_sculpt_check_cavity_curves(Sculpt *sd)
Definition scene.cc:135
char * BKE_paint_canvas_key_get(PaintModeSettings *settings, Object *ob)
A BVH for high poly meshes.
void BKE_pbvh_mark_rebuild_pixels(blender::bke::pbvh::Tree &pbvh)
Definition pbvh.cc:1517
void BKE_pbvh_node_mark_update(blender::bke::pbvh::Node &node)
Definition pbvh.cc:1512
void BKE_pbvh_vert_coords_apply(blender::bke::pbvh::Tree &pbvh, blender::Span< blender::float3 > vert_positions)
Definition pbvh.cc:2398
void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
Definition scene.cc:2573
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
blender::BitGroupVector & BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_grid_hidden_free(SubdivCCG &subdiv_ccg)
int BKE_ccg_gridsize(int level)
Definition CCGSubSurf.cc:25
int BKE_ccg_factor(int low_level, int high_level)
Definition CCGSubSurf.cc:30
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.h:303
#define GHASH_ITER(gh_iter_, ghash_)
Definition BLI_ghash.h:322
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:702
BLI_INLINE float BLI_hash_int_01(unsigned int k)
Definition BLI_hash.h:96
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
int BLI_listbase_count_at_most(const struct ListBase *listbase, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
#define M_PI
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
Definition math_color.cc:21
void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
void cpack_to_rgb(unsigned int col, float *r_r, float *r_g, float *r_b)
MINLINE float len_squared_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3_uchar(unsigned char r[3], const unsigned char a[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.c:40
unsigned char uchar
unsigned int uint
#define POINTER_AS_INT(i)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define STREQ(a, b)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
Definition readfile.cc:4992
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
#define BLO_write_struct_list(writer, struct_name, list_ptr)
#define BLO_read_struct(reader, struct_name, ptr_p)
#define BLT_I18NCONTEXT_ID_PALETTE
#define BLT_I18NCONTEXT_ID_PAINTCURVE
void DEG_id_tag_update(ID *id, unsigned int flags)
Scene * DEG_get_input_scene(const Depsgraph *graph)
Object * DEG_get_original_object(Object *object)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ ID_RECALC_GEOMETRY_ALL_MODES
Definition DNA_ID.h:1148
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:654
@ INDEX_ID_PC
Definition DNA_ID.h:1313
@ INDEX_ID_PAL
Definition DNA_ID.h:1312
#define FILTER_ID_PC
Definition DNA_ID.h:1183
#define FILTER_ID_PAL
Definition DNA_ID.h:1182
@ ID_PAL
@ ID_BR
@ ID_PC
eBrushGPVertexType
@ GPVERTEX_BRUSH_TYPE_BLUR
@ GPVERTEX_BRUSH_TYPE_DRAW
@ GPVERTEX_BRUSH_TYPE_TINT
@ GPVERTEX_BRUSH_TYPE_REPLACE
@ GPVERTEX_BRUSH_TYPE_AVERAGE
@ GPVERTEX_BRUSH_TYPE_SMEAR
eBrushGPaintType
@ GPAINT_BRUSH_TYPE_TINT
@ GPAINT_BRUSH_TYPE_FILL
@ GPAINT_BRUSH_TYPE_DRAW
@ GPAINT_BRUSH_TYPE_ERASE
eBrushWeightPaintType
@ WPAINT_BRUSH_TYPE_BLUR
@ WPAINT_BRUSH_TYPE_AVERAGE
@ WPAINT_BRUSH_TYPE_DRAW
@ WPAINT_BRUSH_TYPE_SMEAR
eBrushSculptType
@ SCULPT_BRUSH_TYPE_DISPLACEMENT_SMEAR
@ SCULPT_BRUSH_TYPE_MASK
@ SCULPT_BRUSH_TYPE_DRAW_FACE_SETS
@ SCULPT_BRUSH_TYPE_SIMPLIFY
@ SCULPT_BRUSH_TYPE_PAINT
@ SCULPT_BRUSH_TYPE_DISPLACEMENT_ERASER
@ SCULPT_BRUSH_TYPE_CLAY_STRIPS
eBrushImagePaintType
@ IMAGE_PAINT_BRUSH_TYPE_MASK
@ IMAGE_PAINT_BRUSH_TYPE_FILL
@ IMAGE_PAINT_BRUSH_TYPE_DRAW
@ IMAGE_PAINT_BRUSH_TYPE_CLONE
@ IMAGE_PAINT_BRUSH_TYPE_SOFTEN
@ IMAGE_PAINT_BRUSH_TYPE_SMEAR
eBrushVertexPaintType
@ VPAINT_BRUSH_TYPE_AVERAGE
@ VPAINT_BRUSH_TYPE_DRAW
@ VPAINT_BRUSH_TYPE_SMEAR
@ VPAINT_BRUSH_TYPE_BLUR
eOverlayFlags
@ BRUSH_OVERLAY_SECONDARY_OVERRIDE_ON_STROKE
@ BRUSH_OVERLAY_PRIMARY_OVERRIDE_ON_STROKE
@ BRUSH_OVERLAY_CURSOR_OVERRIDE_ON_STROKE
#define BRUSH_OVERLAY_OVERRIDE_MASK
eBrushGPWeightType
@ GPWEIGHT_BRUSH_TYPE_AVERAGE
@ GPWEIGHT_BRUSH_TYPE_DRAW
@ GPWEIGHT_BRUSH_TYPE_SMEAR
@ GPWEIGHT_BRUSH_TYPE_BLUR
eBrushGPSculptType
@ GPSCULPT_BRUSH_TYPE_CLONE
eBrushCurvesSculptType
@ CURVES_SCULPT_BRUSH_TYPE_ADD
@ CURVES_SCULPT_BRUSH_TYPE_DENSITY
@ CURVES_SCULPT_BRUSH_TYPE_DELETE
@ CURVES_SCULPT_BRUSH_TYPE_SELECTION_PAINT
struct PaintCurve PaintCurve
struct Palette Palette
@ CURVE_PRESET_LINE
@ CD_PROP_COLOR
@ CD_PROP_INT32
@ CD_GRID_PAINT_MASK
#define DNA_struct_default_get(struct_name)
@ ME_EDIT_PAINT_VERT_SEL
@ ME_EDIT_PAINT_FACE_SEL
@ eMultiresModifierFlag_UseSculptBaseMesh
@ eModifierMode_Realtime
@ eModifierType_ShapeKey
@ eModifierType_Multires
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_OBJECT
@ OB_MODE_WEIGHT_GREASE_PENCIL
@ OB_MODE_VERTEX_PAINT
Object is a sort of wrapper for general info.
@ OB_SHAPE_LOCK
@ OB_GREASE_PENCIL
@ OB_MESH
@ OB_GPENCIL_LEGACY
@ SCULPT_ONLY_DEFORM
@ UNIFIED_PAINT_COLOR
@ PAINT_SHOW_BRUSH
@ SPACE_IMAGE
@ SPACE_VIEW3D
@ SI_MODE_PAINT
@ MTEX_ANGLE_RAKE
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
@ BM_ELEM_HIDDEN
#define BM_FACE_FIRST_LOOP(p)
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
void BM_data_layer_ensure_named(BMesh *bm, CustomData *data, int type, const char *name)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_log_free(BMLog *log)
Definition bmesh_log.cc:545
void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
Definition bmesh_log.cc:573
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParams *params)
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned int U
Definition btGjkEpa3.h:78
static unsigned long seed
Definition btSoftBody.h:39
static AttributeOwner from_id(ID *id)
Definition attribute.cc:43
int64_t size() const
Definition BLI_array.hh:245
const T * data() const
Definition BLI_array.hh:301
bool is_empty() const
Definition BLI_array.hh:253
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:138
constexpr const T * data() const
Definition BLI_span.hh:216
constexpr bool is_empty() const
constexpr const char * c_str() const
void tag_positions_changed(const IndexMask &node_mask)
Definition pbvh.cc:549
static Tree from_bmesh(BMesh &bm)
Span< NodeT > nodes() const
static Tree from_grids(const Mesh &base_mesh, const SubdivCCG &subdiv_ccg)
Definition pbvh.cc:389
static Tree from_mesh(const Mesh &mesh)
Definition pbvh.cc:234
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
#define atan2f(x, y)
#define floorf(x)
#define offsetof(t, d)
draw_view in_light_buf[] float
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:43
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
static ulong * next
pbvh::Tree & pbvh_ensure(Depsgraph &depsgraph, Object &object)
Definition paint.cc:2811
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2846
void update_normals_from_eval(Object &object_eval, Tree &pbvh)
Definition pbvh.cc:1065
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:2482
ID * asset_edit_id_from_weak_reference(Main &global_main, ID_Type id_type, const AssetWeakReference &weak_ref)
static std::unique_ptr< pbvh::Tree > build_pbvh_from_regular_mesh(Object *ob, const Mesh *me_eval_deform)
Definition paint.cc:2785
std::optional< AssetWeakReference > asset_edit_weak_reference_from_id(const ID &id)
static std::unique_ptr< pbvh::Tree > build_pbvh_from_ccg(Object *ob, SubdivCCG &subdiv_ccg)
Definition paint.cc:2799
static std::unique_ptr< pbvh::Tree > build_pbvh_for_dynamic_topology(Object *ob)
Definition paint.cc:2776
bool asset_edit_id_is_editable(const ID &id)
CartesianBasis invert(const CartesianBasis &basis)
static void unique_name(bNode *node)
void BKE_palette_sort_vhs(tPaletteColorHSV *color_array, const int totcol)
Definition paint.cc:1532
Brush * BKE_paint_brush_from_essentials(Main *bmain, const eObjectMode ob_mode, const char *name)
Definition paint.cc:789
void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
Definition paint.cc:2568
PaletteColor * BKE_palette_color_add(Palette *palette)
Definition paint.cc:1392
bool BKE_paint_eraser_brush_set_default(Main *bmain, Paint *paint)
Definition paint.cc:1202
bool BKE_paint_select_grease_pencil_test(const Object *ob)
Definition paint.cc:1621
void BKE_paint_cavity_curve_preset(Paint *paint, int preset)
Definition paint.cc:1644
void BKE_paint_set_overlay_override(eOverlayFlags flags)
Definition paint.cc:297
Brush * BKE_paint_eraser_brush(Paint *paint)
Definition paint.cc:1155
const EnumPropertyItem * BKE_paint_get_tool_enum_from_paintmode(const PaintMode mode)
Definition paint.cc:408
static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
Definition paint.cc:2322
static bool paint_brush_update_from_asset_reference(Main *bmain, Paint *paint)
Definition paint.cc:619
const uchar PAINT_CURSOR_SCULPT_GREASE_PENCIL[3]
Definition paint.cc:249
void BKE_paint_invalidate_cursor_overlay(Scene *scene, ViewLayer *view_layer, CurveMapping *curve)
Definition paint.cc:273
float paint_grid_paint_mask(const GridPaintMask *gpm, uint level, uint x, uint y)
Definition paint.cc:1966
bool BKE_paint_brush_set_essentials(Main *bmain, Paint *paint, const char *name)
Definition paint.cc:1102
void BKE_sculpt_sync_face_visibility_to_grids(const Mesh &mesh, SubdivCCG &subdiv_ccg)
Definition paint.cc:2747
void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex)
Definition paint.cc:253
static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
Definition paint.cc:2072
void BKE_paint_copy(const Paint *src, Paint *dst, const int flag)
Definition paint.cc:1818
static bool paint_rake_rotation_active(const MTex &mtex)
Definition paint.cc:1994
void BKE_sculptsession_bm_to_me(Object *ob, bool reorder)
Definition paint.cc:2088
bool paint_calculate_rake_rotation(UnifiedPaintSettings &ups, const Brush &brush, const float mouse_pos[2], const PaintMode paint_mode, bool stroke_has_started)
Definition paint.cc:2005
static MultiresModifierData * sculpt_multires_modifier_get(const Scene *scene, Object *ob, const bool auto_create_mdisps)
Definition paint.cc:2263
bool BKE_paint_always_hide_test(const Object *ob)
Definition paint.cc:1638
PaintCurve * BKE_paint_curve_add(Main *bmain, const char *name)
Definition paint.cc:1339
std::optional< int > BKE_paint_get_brush_type_from_obmode(const Brush *brush, const eObjectMode ob_mode)
Definition paint.cc:1280
static bool check_sculpt_object_deformed(Object *object, const bool for_construction)
Definition paint.cc:2725
bool BKE_palette_from_hash(Main *bmain, GHash *color_table, const char *name, const bool linear)
Definition paint.cc:1544
bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d)
Definition paint.cc:2862
void BKE_paint_brushes_ensure(Main *bmain, Paint *paint)
Definition paint.cc:1762
static AssetWeakReference * asset_reference_create_from_brush(Brush *brush)
Definition paint.cc:667
const uchar PAINT_CURSOR_PAINT_GREASE_PENCIL[3]
Definition paint.cc:248
static int palettecolor_compare_luminance(const void *a1, const void *a2)
Definition paint.cc:1502
void BKE_sculptsession_free(Object *ob)
Definition paint.cc:2145
bool BKE_paint_use_unified_color(const ToolSettings *tool_settings, const Paint *paint)
Definition paint.cc:605
bool BKE_paint_brush_set(Main *bmain, Paint *paint, const AssetWeakReference *brush_asset_reference)
Definition paint.cc:678
static void paint_brush_default_essentials_name_get(eObjectMode ob_mode, std::optional< int > brush_type, blender::StringRefNull *r_name, blender::StringRefNull *r_eraser_name=nullptr)
Definition paint.cc:823
static void palette_copy_data(Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int)
Definition paint.cc:99
const uchar PAINT_CURSOR_WEIGHT_PAINT[3]
Definition paint.cc:245
void BKE_sculptsession_free_deformMats(SculptSession *ss)
Definition paint.cc:2049
bool BKE_paint_select_elem_test(const Object *ob)
Definition paint.cc:1632
Paint * BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
Definition paint.cc:438
ePaintOverlayControlFlags BKE_paint_get_overlay_flags()
Definition paint.cc:292
static bool paint_eraser_brush_set_from_asset_reference(Main *bmain, Paint *paint)
Definition paint.cc:1125
bool BKE_paint_select_vert_test(const Object *ob)
Definition paint.cc:1614
static float paint_rake_rotation_spacing(const UnifiedPaintSettings &, const Brush &brush)
Definition paint.cc:1975
void BKE_palette_color_remove(Palette *palette, PaletteColor *color)
Definition paint.cc:1364
void BKE_sculptsession_free_vwpaint_data(SculptSession *ss)
Definition paint.cc:2057
bool paint_is_grid_face_hidden(const blender::BoundedBitSpan grid_hidden, const int gridsize, const int x, const int y)
Definition paint.cc:1940
static const char * paint_brush_essentials_asset_file_name_from_obmode(const eObjectMode ob_mode)
Definition paint.cc:731
uint BKE_paint_get_brush_type_offset_from_paintmode(const PaintMode mode)
Definition paint.cc:1250
void BKE_paint_stroke_get_average(const Scene *scene, const Object *ob, float stroke[3])
Definition paint.cc:1850
const Brush * BKE_paint_eraser_brush_for_read(const Paint *paint)
Definition paint.cc:1160
void BKE_sculpt_update_object_before_eval(Object *ob_eval)
Definition paint.cc:2509
void BKE_palette_sort_hsv(tPaletteColorHSV *color_array, const int totcol)
Definition paint.cc:1520
static int palettecolor_compare_svh(const void *a1, const void *a2)
Definition paint.cc:1438
void BKE_paint_reset_overlay_invalid(ePaintOverlayControlFlags flag)
Definition paint.cc:315
void BKE_palette_sort_svh(tPaletteColorHSV *color_array, const int totcol)
Definition paint.cc:1526
static void paint_curve_copy_data(Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int)
Definition paint.cc:174
static void paint_runtime_init(const ToolSettings *ts, Paint *paint)
Definition paint.cc:1214
void BKE_paint_free(Paint *paint)
Definition paint.cc:1801
void paint_update_brush_rake_rotation(UnifiedPaintSettings &ups, const Brush &brush, float rotation)
Definition paint.cc:1980
static AssetWeakReference * paint_brush_asset_reference_ptr_from_essentials(const char *name, const eObjectMode ob_mode)
Definition paint.cc:757
void BKE_palette_sort_luminance(tPaletteColorHSV *color_array, const int totcol)
Definition paint.cc:1538
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:654
bool BKE_paint_eraser_brush_set(Paint *paint, Brush *brush)
Definition paint.cc:1165
static void palette_free_data(ID *id)
Definition paint.cc:111
static void palette_undo_preserve(BlendLibReader *, ID *id_new, ID *id_old)
Definition paint.cc:134
static void paint_curve_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition paint.cc:197
Paint * BKE_paint_get_active_from_paintmode(Scene *sce, PaintMode mode)
Definition paint.cc:371
eObjectMode BKE_paint_object_mode_from_paintmode(const PaintMode mode)
Definition paint.cc:1661
MultiresModifierData * BKE_sculpt_multires_active(const Scene *scene, Object *ob)
Definition paint.cc:2316
void BKE_paint_init(Main *bmain, Scene *sce, PaintMode mode, const uchar col[3], const bool ensure_brushes)
Definition paint.cc:1779
static void paint_curve_free_data(ID *id)
Definition paint.cc:189
Brush * BKE_paint_eraser_brush_from_essentials(Main *bmain, eObjectMode ob_mode, const char *name)
Definition paint.cc:1190
void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bool is_paint_tool)
Definition paint.cc:2601
#define GOLDEN_RATIO_CONJUGATE
Definition paint.cc:2885
void BKE_sculpt_color_layer_create_if_needed(Object *object)
Definition paint.cc:2577
void BKE_palette_clear(Palette *palette)
Definition paint.cc:1380
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:477
bool paint_is_bmesh_face_hidden(const BMFace *f)
Definition paint.cc:1951
void BKE_sculptsession_bm_to_me_for_render(Object *object)
Definition paint.cc:2123
static std::optional< AssetWeakReference > paint_brush_asset_reference_from_essentials(const char *name, const eObjectMode ob_mode)
Definition paint.cc:773
bool BKE_paint_ensure(ToolSettings *ts, Paint **r_paint)
Definition paint.cc:1685
static ePaintOverlayControlFlags overlay_flags
Definition paint.cc:251
std::optional< AssetWeakReference > BKE_paint_brush_type_default_reference(eObjectMode ob_mode, std::optional< int > brush_type)
Definition paint.cc:1030
bool BKE_paint_brush_set_default(Main *bmain, Paint *paint)
Definition paint.cc:1096
Palette * BKE_palette_add(Main *bmain, const char *name)
Definition paint.cc:1386
const uchar PAINT_CURSOR_SCULPT[3]
Definition paint.cc:243
static void sculpt_update_object(Depsgraph *depsgraph, Object *ob, Object *ob_eval, bool is_paint_tool)
Definition paint.cc:2366
IDTypeInfo IDType_ID_PAL
Definition paint.cc:144
static void palette_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition paint.cc:118
bool BKE_paint_eraser_brush_set_essentials(Main *bmain, Paint *paint, const char *name)
Definition paint.cc:1208
const uchar PAINT_CURSOR_TEXTURE_PAINT[3]
Definition paint.cc:246
static void paint_curve_blend_read_data(BlendDataReader *reader, ID *id)
Definition paint.cc:207
IDTypeInfo IDType_ID_PC
Definition paint.cc:213
void BKE_sculptsession_free_pbvh(Object &object)
Definition paint.cc:2099
static int palettecolor_compare_vhs(const void *a1, const void *a2)
Definition paint.cc:1470
static void palette_init_data(ID *id)
Definition paint.cc:89
static int palettecolor_compare_hsv(const void *a1, const void *a2)
Definition paint.cc:1405
static void paint_eraser_brush_set_essentials_reference(Paint *paint, const char *name)
Definition paint.cc:812
void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Paint *paint)
Definition paint.cc:1894
static void paint_brush_set_default_reference(Paint *paint, const bool do_regular=true, const bool do_eraser=true)
Definition paint.cc:1043
void BKE_paint_face_set_overlay_color_get(const int face_set, const int seed, uchar r_color[4])
Definition paint.cc:2886
static void paint_brush_set_essentials_reference(Paint *paint, const char *name)
Definition paint.cc:801
std::optional< int > BKE_paint_get_brush_type_from_paintmode(const Brush *brush, const PaintMode mode)
Definition paint.cc:1308
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:649
void BKE_sculpt_toolsettings_data_ensure(Main *bmain, Scene *scene)
Definition paint.cc:2678
Palette * BKE_paint_palette(Paint *paint)
Definition paint.cc:1345
void BKE_paint_palette_set(Paint *paint, Palette *palette)
Definition paint.cc:1350
const uchar PAINT_CURSOR_SCULPT_CURVES[3]
Definition paint.cc:247
void BKE_paint_curve_clamp_endpoint_add_index(PaintCurve *pc, const int add_index)
Definition paint.cc:1359
bool BKE_palette_is_empty(const Palette *palette)
Definition paint.cc:1399
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
Definition paint.cc:506
const uchar PAINT_CURSOR_VERTEX_PAINT[3]
Definition paint.cc:244
static void palette_blend_read_data(BlendDataReader *reader, ID *id)
Definition paint.cc:128
void BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, Main *bmain, Object *ob, MultiresModifierData *mmd)
Definition paint.cc:2610
bool BKE_paint_brush_poll(const Paint *paint, const Brush *brush)
Definition paint.cc:659
bool BKE_object_sculpt_use_dyntopo(const Object *object)
Definition paint.cc:2857
void BKE_paint_brushes_set_default_references(ToolSettings *ts)
Definition paint.cc:1067
bool BKE_paint_select_face_test(const Object *ob)
Definition paint.cc:1607
PaintMode BKE_paintmode_get_from_tool(const bToolRef *tref)
Definition paint.cc:565
void BKE_paint_brushes_validate(Main *bmain, Paint *paint)
Definition paint.cc:1108
void BKE_paint_invalidate_overlay_all()
Definition paint.cc:286
void BKE_paint_blend_write(BlendWriter *writer, Paint *paint)
Definition paint.cc:1862
bool BKE_paint_ensure_from_paintmode(Scene *sce, PaintMode mode)
Definition paint.cc:320
const EnumPropertyItem rna_enum_brush_weight_brush_type_items[]
Definition rna_brush.cc:206
const EnumPropertyItem rna_enum_brush_gpencil_sculpt_types_items[]
Definition rna_brush.cc:269
const EnumPropertyItem rna_enum_brush_image_brush_type_items[]
Definition rna_brush.cc:214
const EnumPropertyItem rna_enum_brush_sculpt_brush_type_items[]
Definition rna_brush.cc:151
const EnumPropertyItem rna_enum_brush_gpencil_vertex_types_items[]
Definition rna_brush.cc:244
const EnumPropertyItem rna_enum_brush_gpencil_weight_types_items[]
Definition rna_brush.cc:305
const EnumPropertyItem rna_enum_brush_vertex_brush_type_items[]
Definition rna_brush.cc:198
const EnumPropertyItem rna_enum_brush_gpencil_types_items[]
Definition rna_brush.cc:224
const EnumPropertyItem rna_enum_brush_curves_sculpt_brush_type_items[]
Definition rna_brush.cc:317
const char * relative_asset_identifier
const char * asset_library_identifier
struct BMVert * v
struct BMLoop * next
float co[3]
CustomData vdata
CustomData pdata
char sculpt_brush_type
struct MTex mtex
char gpencil_sculpt_brush_type
short ob_mode
char image_brush_type
struct CurveMapping * curve
char gpencil_weight_brush_type
char gpencil_vertex_brush_type
char curves_sculpt_brush_type
struct MTex mask_mtex
char gpencil_brush_type
char weight_brush_type
char vertex_brush_type
CurveMap cm[4]
Definition DNA_ID.h:413
IDProperty * properties
Definition DNA_ID.h:456
void * data
char brush_angle_mode
struct Tex * tex
bool is_locked_for_linking
Definition BKE_main.hh:176
int corners_num
MeshRuntimeHandle * runtime
int faces_num
int verts_num
char * active_color_attribute
struct ModifierData * next
ModifierTypeType type
struct SculptSession * sculpt
PaintCurvePoint * points
unsigned int initialized
unsigned short ob_mode
struct Paint_Runtime runtime
float tile_offset[3]
struct Brush * eraser_brush
void * paint_cursor
unsigned char paint_cursor_col[4]
struct CurveMapping * cavity_curve
struct AssetWeakReference * eraser_brush_asset_reference
struct Palette * palette
struct AssetWeakReference * brush_asset_reference
struct Brush * brush
ToolSystemBrushBindings tool_brush_bindings
ListBase colors
struct ViewRender * view_render
struct ToolSettings * toolsettings
blender::Array< int > fake_neighbor_index
Definition BKE_paint.hh:366
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:427
BMLog * bm_log
Definition BKE_paint.hh:402
void clear_active_vert(bool persist_last_active)
Definition paint.cc:2245
blender::ed::sculpt_paint::filter::Cache * filter_cache
Definition BKE_paint.hh:428
KeyBlock * shapekey_active
Definition BKE_paint.hh:387
blender::Array< int > vert_to_edge_indices
Definition BKE_paint.hh:396
SculptVertexInfo vertex_info
Definition BKE_paint.hh:458
blender::SharedCache< blender::Vector< blender::float3 > > face_normals_deform
Definition BKE_paint.hh:422
blender::GroupedSpan< int > vert_to_edge_map
Definition BKE_paint.hh:397
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
blender::Array< MDeformVert > dvert_prev
Definition BKE_paint.hh:481
blender::Array< int > preview_verts
Definition BKE_paint.hh:450
ActiveVert active_vert() const
Definition paint.cc:2180
blender::Array< int > edge_to_face_offsets
Definition BKE_paint.hh:390
blender::Array< blender::float3, 0 > deform_cos
Definition BKE_paint.hh:413
blender::float3 active_vert_position(const Depsgraph &depsgraph, const Object &object) const
Definition paint.cc:2224
int last_active_vert_index() const
Definition paint.cc:2207
float * alpha_weight
Definition BKE_paint.hh:477
ImagePool * tex_pool
Definition BKE_paint.hh:425
struct SculptSession::@49 mode
std::unique_ptr< blender::bke::pbvh::Tree > pbvh
Definition BKE_paint.hh:408
std::unique_ptr< SculptTopologyIslandCache > topology_island_cache
Definition BKE_paint.hh:513
char * last_paint_canvas_key
Definition BKE_paint.hh:510
blender::Array< int > vert_to_edge_offsets
Definition BKE_paint.hh:395
blender::GroupedSpan< int > edge_to_face_map
Definition BKE_paint.hh:392
blender::SharedCache< blender::Vector< blender::float3 > > vert_normals_deform
Definition BKE_paint.hh:421
blender::ed::sculpt_paint::expand::Cache * expand_cache
Definition BKE_paint.hh:429
int active_vert_index() const
Definition paint.cc:2190
eObjectMode mode_type
Definition BKE_paint.hh:487
struct SculptSession::@49::@50 wpaint
ActiveVert last_active_vert() const
Definition paint.cc:2185
blender::Array< int > edge_to_face_indices
Definition BKE_paint.hh:391
blender::Array< blender::float3x3, 0 > deform_imats
Definition BKE_paint.hh:415
struct SculptSession::@48 multires
MultiresModifierData * modifier
Definition BKE_paint.hh:383
SculptFakeNeighbors fake_neighbors
Definition BKE_paint.hh:459
bool building_vp_handle
Definition BKE_paint.hh:491
bool deform_modifiers_active
Definition BKE_paint.hh:411
void set_active_vert(ActiveVert vert)
Definition paint.cc:2258
blender::BitVector boundary
Definition BKE_paint.hh:351
float automasking_start_normal_falloff
float detail_percent
float automasking_view_normal_limit
float detail_size
struct CurveMapping * automasking_cavity_curve_op
float automasking_start_normal_limit
struct CurveMapping * automasking_cavity_curve
float constant_detail
float automasking_view_normal_falloff
int to_index(const CCGKey &key) const
blender::Array< blender::float3 > positions
GpWeightPaint * gp_weightpaint
struct ImagePaintSettings imapaint
GpSculptPaint * gp_sculptpaint
struct UnifiedPaintSettings unified_paint_settings
CurvesSculpt * curves_sculpt
GpVertexPaint * gp_vertexpaint
struct AssetWeakReference * main_brush_asset_reference
#define N_(msgid)
uint8_t flag
Definition wm_window.cc:138