Blender V5.0
brush_asset_ops.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_fileops.h"
6#include "BLI_listbase.h"
7#include "BLI_path_utils.hh"
8#include "BLI_string_utf8.h"
9
10#include "DNA_brush_types.h"
11#include "DNA_scene_types.h"
12#include "DNA_space_types.h"
13#include "DNA_userdef_types.h"
14
15#include "BKE_asset.hh"
16#include "BKE_asset_edit.hh"
17#include "BKE_blendfile.hh"
18#include "BKE_brush.hh"
19#include "BKE_context.hh"
20#include "BKE_global.hh"
21#include "BKE_lib_id.hh"
22#include "BKE_paint.hh"
23#include "BKE_paint_types.hh"
24#include "BKE_preferences.h"
25#include "BKE_preview_image.hh"
26#include "BKE_report.hh"
27
29#include "AS_asset_library.hh"
31
32#include "RNA_access.hh"
33#include "RNA_define.hh"
34
35#include "ED_asset.hh"
36#include "ED_asset_library.hh"
37#include "ED_asset_list.hh"
40#include "ED_asset_shelf.hh"
41
42#include "UI_interface_icons.hh"
43
44#include "BLT_translation.hh"
45
46#include "WM_api.hh"
47#include "WM_toolsystem.hh"
48
49#include "paint_intern.hh"
50
52
54{
55 /* This operator currently covers both cases: the file/asset browser file list and the asset list
56 * used for the asset-view template. Once the asset list design is used by the Asset Browser,
57 * this can be simplified to just that case. */
58 Main *bmain = CTX_data_main(C);
59
60 if (G.background) {
61 /* As asset loading can take upwards of a few minutes on production libraries, we typically
62 * do not want this to execute in a blocking fashion. However, for testing / profiling
63 * purposes, this is an acceptable workaround for now until a proper python API is created
64 * for this use case. */
66 }
69 if (!asset) {
70 return OPERATOR_CANCELLED;
71 }
72
73 const bool use_toggle = RNA_boolean_get(op->ptr, "use_toggle");
74 AssetWeakReference brush_asset_reference = asset->make_weak_reference();
76 std::optional<AssetWeakReference> asset_to_save;
77 if (use_toggle) {
78 BLI_assert(paint->brush_asset_reference);
79 if (brush_asset_reference == *paint->brush_asset_reference) {
80 if (paint->runtime->previous_active_brush_reference != nullptr) {
81 brush_asset_reference = *paint->runtime->previous_active_brush_reference;
82 }
83 }
84 else {
85 asset_to_save = *paint->brush_asset_reference;
86 }
87 }
88 Brush *brush = reinterpret_cast<Brush *>(
89 bke::asset_edit_id_from_weak_reference(*bmain, ID_BR, brush_asset_reference));
90
91 /* Activate brush through tool system rather than calling #BKE_paint_brush_set() directly, to let
92 * the tool system switch tools if necessary, and update which brush was the last recently used
93 * one for the current tool. */
95 /* Note brush datablock was still added, so was not a no-op. */
96 BKE_report(op->reports, RPT_WARNING, "Unable to activate brush, wrong object mode");
97 return OPERATOR_FINISHED;
98 }
99
100 if (asset_to_save) {
101 BKE_paint_previous_asset_reference_set(paint, std::move(*asset_to_save));
102 }
103 else if (!use_toggle) {
104 /* If we aren't toggling, clear the previous reference so that we don't swap back to an
105 * incorrect "previous" asset */
107 }
108
111
112 return OPERATOR_FINISHED;
113}
114
116{
117 ot->name = "Activate Brush Asset";
118 ot->description = "Activate a brush asset as current sculpt and paint tool";
119 ot->idname = "BRUSH_OT_asset_activate";
120
122
124 PropertyRNA *prop;
125 prop = RNA_def_boolean(ot->srna,
126 "use_toggle",
127 false,
128 "Toggle",
129 "Switch between the current and assigned brushes on consecutive uses.");
131}
132
134{
136 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
137 if (paint == nullptr || brush == nullptr) {
138 return false;
139 }
140 if (!paint->brush_asset_reference) {
141 /* The brush should always be an imported asset. We use this asset reference to find
142 * which library and catalog the brush came from, as defaults for the popup. */
143 return false;
144 }
145
146 return true;
147}
148
150{
151 Main *bmain = CTX_data_main(C);
153 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
154
155 /* Determine file path to save to. */
156 PropertyRNA *name_prop = RNA_struct_find_property(op->ptr, "name");
157 /* FIXME: MAX_ID_NAME & FILE_MAXFILE
158 *
159 * This `name` should be `MAX_ID_NAME - 2` long.
160 *
161 * This name might also be used as filename for the saved asset, thus hitting the size issue
162 * between ID names and file names (FILE_MAXFILE). */
163 char name[MAX_NAME] = "";
164 if (RNA_property_is_set(op->ptr, name_prop)) {
165 RNA_property_string_get(op->ptr, name_prop, name);
166 }
167 if (name[0] == '\0') {
168 STRNCPY_UTF8(name, brush->id.name + 2);
169 }
170
171 const eAssetLibraryType enum_value = (eAssetLibraryType)RNA_enum_get(op->ptr,
172 "asset_library_reference");
173 const bool is_local_library = enum_value == ASSET_LIBRARY_LOCAL;
174
175 AssetLibraryReference library_reference;
176 const bUserAssetLibrary *user_library = nullptr;
177 if (is_local_library) {
179 }
180 else {
181 user_library = asset::get_asset_library_from_opptr(*op->ptr);
182 if (!user_library) {
183 return OPERATOR_CANCELLED;
184 }
185 library_reference = asset::user_library_to_library_ref(*user_library);
186 }
187 asset_system::AssetLibrary *library = AS_asset_library_load(bmain, library_reference);
188 if (!library) {
189 BKE_report(op->reports, RPT_ERROR, "Failed to load asset library");
190 return OPERATOR_CANCELLED;
191 }
192
193 BLI_assert(is_local_library || user_library);
194
195 /* Turn brush into asset if it isn't yet. */
196 if (!ID_IS_ASSET(&brush->id)) {
197 asset::mark_id(&brush->id);
198 asset::generate_preview(C, &brush->id);
199 }
200 BLI_assert(ID_IS_ASSET(&brush->id));
201
202 if (is_local_library) {
203 const Brush *original_brush = brush;
204 brush = BKE_brush_duplicate(
206
207 BKE_libblock_rename(*bmain, brush->id, name);
208 asset::mark_id(&brush->id);
209 BLI_assert(brush->id.us == 1);
210
212 brush->id.asset_data = BKE_asset_metadata_copy(original_brush->id.asset_data);
213 BLI_assert(brush->id.asset_data != nullptr);
214 }
215
216 /* Add asset to catalog. */
217 /* Note: This needs to happen after the local asset is created but BEFORE a non-local library
218 * is saved */
219 char catalog_path_c[MAX_NAME];
220 RNA_string_get(op->ptr, "catalog_path", catalog_path_c);
221
222 AssetMetaData &meta_data = *brush->id.asset_data;
223 if (catalog_path_c[0]) {
224 const asset_system::AssetCatalogPath catalog_path(catalog_path_c);
226 *library, catalog_path);
227 BKE_asset_metadata_catalog_id_set(&meta_data, catalog.catalog_id, catalog.simple_name.c_str());
228 }
229
230 if (!is_local_library) {
231 AssetWeakReference brush_asset_reference;
232 const std::optional<std::string> final_full_asset_filepath = bke::asset_edit_id_save_as(
233 *bmain, brush->id, name, *user_library, brush_asset_reference, *op->reports);
234 if (!final_full_asset_filepath) {
235 return OPERATOR_CANCELLED;
236 }
237 library->catalog_service().write_to_disk(*final_full_asset_filepath);
238
239 brush = reinterpret_cast<Brush *>(
240 bke::asset_edit_id_from_weak_reference(*bmain, ID_BR, brush_asset_reference));
241 brush->has_unsaved_changes = false;
242 }
243
245
247 /* Note brush asset was still saved in editable asset library, so was not a no-op. */
248 BKE_report(op->reports, RPT_WARNING, "Unable to activate just-saved brush asset");
249 }
250
251 asset::refresh_asset_library(C, library_reference);
253 if (is_local_library) {
256 }
257 else {
259 }
260
261 return OPERATOR_FINISHED;
262}
263
265{
266 if (library.type == ASSET_LIBRARY_ESSENTIALS) {
267 return false;
268 }
269 return true;
270}
271
273 wmOperator *op,
274 const wmEvent * /*event*/)
275{
277 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
279 *C, brush_weak_ref, op->reports);
280 if (!asset) {
281 return OPERATOR_CANCELLED;
282 }
283 const asset_system::AssetLibrary &library = asset->owner_asset_library();
284 const std::optional<AssetLibraryReference> library_ref = library.library_reference();
285 if (!library_ref) {
287 return OPERATOR_CANCELLED;
288 }
289
290 RNA_string_set(op->ptr, "name", asset->get_name().c_str());
291
292 /* If the library isn't saved from the operator's last execution, find the current library or the
293 * first library if the current library isn't editable. */
294 if (!RNA_struct_property_is_set_ex(op->ptr, "asset_library_reference", false)) {
295 if (library_is_editable(*library_ref)) {
296 RNA_enum_set(op->ptr,
297 "asset_library_reference",
299 }
300 else {
302 *static_cast<const bUserAssetLibrary *>(U.asset_libraries.first));
303 RNA_enum_set(op->ptr,
304 "asset_library_reference",
306 }
307 }
308
309 /* By default, put the new asset in the same catalog as the existing asset. */
310 if (!RNA_struct_property_is_set(op->ptr, "catalog_path")) {
311 const asset_system::CatalogID &id = asset->get_metadata().catalog_id;
312 if (const asset_system::AssetCatalog *catalog = library.catalog_service().find_catalog(id)) {
313 RNA_string_set(op->ptr, "catalog_path", catalog->path.c_str());
314 }
315 }
316
317 return WM_operator_props_dialog_popup(C, op, 400, std::nullopt, IFACE_("Save"));
318}
319
321 PointerRNA * /*ptr*/,
322 PropertyRNA * /*prop*/,
323 bool *r_free)
324{
326 /* Only get writable libraries. */
327 /*include_readonly=*/false,
328 /*include_current_file=*/true);
329 if (!items) {
330 *r_free = false;
331 return nullptr;
332 }
333
334 *r_free = true;
335 return items;
336}
337
339 const bContext *C,
341 PropertyRNA * /*prop*/,
342 const char *edit_text,
344{
345 /* NOTE: Using the all library would also be a valid choice. */
348}
349
351{
352 ot->name = "Save as Brush Asset";
353 ot->description =
354 "Save a copy of the active brush asset into the default asset library, and make it the "
355 "active brush";
356 ot->idname = "BRUSH_OT_asset_save_as";
357
361
362 ot->prop = RNA_def_string(
363 ot->srna, "name", nullptr, MAX_NAME, "Name", "Name for the new brush asset");
364
365 PropertyRNA *prop = RNA_def_property(ot->srna, "asset_library_reference", PROP_ENUM, PROP_NONE);
367 RNA_def_property_ui_text(prop, "Library", "Asset library used to store the new brush");
368
369 prop = RNA_def_string(
370 ot->srna, "catalog_path", nullptr, MAX_NAME, "Catalog", "Catalog to use for the new asset");
373}
374
376{
377 Main *bmain = CTX_data_main(C);
379 Brush *brush = BKE_paint_brush(paint);
380 BLI_assert(ID_IS_ASSET(&brush->id));
381 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
383 *C, brush_weak_ref, op->reports);
384 if (!asset) {
385 return OPERATOR_CANCELLED;
386 }
387 asset_system::AssetLibrary &library = asset->owner_asset_library();
388
389 char catalog_path_c[MAX_NAME];
390 RNA_string_get(op->ptr, "catalog_path", catalog_path_c);
391
392 AssetMetaData &meta_data = *brush->id.asset_data;
393 MEM_SAFE_FREE(meta_data.author);
394 meta_data.author = RNA_string_get_alloc(op->ptr, "author", nullptr, 0, nullptr);
395 MEM_SAFE_FREE(meta_data.description);
396 meta_data.description = RNA_string_get_alloc(op->ptr, "description", nullptr, 0, nullptr);
397
398 if (catalog_path_c[0]) {
399 const asset_system::AssetCatalogPath catalog_path(catalog_path_c);
401 library, catalog_path);
402 BKE_asset_metadata_catalog_id_set(&meta_data, catalog.catalog_id, catalog.simple_name.c_str());
403 }
404
405 if (!bke::asset_edit_id_save(*bmain, brush->id, *op->reports)) {
406 return OPERATOR_CANCELLED;
407 }
408
409 asset::catalogs_save_from_asset_reference(library, brush_weak_ref);
410
413
414 return OPERATOR_FINISHED;
415}
416
418 wmOperator *op,
419 const wmEvent * /*event*/)
420{
422 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
424 *C, brush_weak_ref, op->reports);
425 if (!asset) {
426 return OPERATOR_CANCELLED;
427 }
428 const asset_system::AssetLibrary &library = asset->owner_asset_library();
429 const AssetMetaData &meta_data = asset->get_metadata();
430
431 if (!RNA_struct_property_is_set(op->ptr, "catalog_path")) {
432 const asset_system::CatalogID &id = meta_data.catalog_id;
433 if (const asset_system::AssetCatalog *catalog = library.catalog_service().find_catalog(id)) {
434 RNA_string_set(op->ptr, "catalog_path", catalog->path.c_str());
435 }
436 }
437 if (!RNA_struct_property_is_set(op->ptr, "author")) {
438 RNA_string_set(op->ptr, "author", meta_data.author ? meta_data.author : "");
439 }
440 if (!RNA_struct_property_is_set(op->ptr, "description")) {
441 RNA_string_set(op->ptr, "description", meta_data.description ? meta_data.description : "");
442 }
443
444 return WM_operator_props_dialog_popup(C, op, 400, std::nullopt, IFACE_("Edit Metadata"));
445}
446
448 const bContext *C,
449 PointerRNA * /*ptr*/,
450 PropertyRNA * /*prop*/,
451 const char *edit_text,
453{
455 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
457 *C, brush_weak_ref, nullptr);
458 if (!asset) {
459 return;
460 }
461
462 const asset_system::AssetLibrary &library = asset->owner_asset_library();
463
464 /* NOTE: Using the all library would also be a valid choice. */
466 *CTX_data_main(C), *library.library_reference(), edit_text, visit_fn);
467}
468
470{
472 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
473 if (paint == nullptr || brush == nullptr) {
474 return false;
475 }
476 if (!ID_IS_ASSET(&brush->id)) {
478 return false;
479 }
480 const AssetWeakReference *brush_weak_ref = paint->brush_asset_reference;
481 if (!brush_weak_ref) {
483 return false;
484 }
486 *C, *brush_weak_ref, CTX_wm_reports(C));
487 if (!asset) {
488 /* May happen if library loading hasn't finished. */
489 return false;
490 }
491 const std::optional<AssetLibraryReference> library_ref =
492 asset->owner_asset_library().library_reference();
493 if (!library_ref) {
495 return false;
496 }
497 if (!library_is_editable(*library_ref)) {
498 CTX_wm_operator_poll_msg_set(C, "Asset library is not editable");
499 return false;
500 }
501 if (!(library_ref->type & ASSET_LIBRARY_LOCAL) && !bke::asset_edit_id_is_writable(brush->id)) {
502 CTX_wm_operator_poll_msg_set(C, "Asset file is not editable");
503 return false;
504 }
505 return true;
506}
507
509{
510 ot->name = "Edit Metadata";
511 ot->description = "Edit asset information like the catalog, preview image, tags, or author";
512 ot->idname = "BRUSH_OT_asset_edit_metadata";
513
517
519 ot->srna, "catalog_path", nullptr, MAX_NAME, "Catalog", "The asset's catalog path");
522 RNA_def_string(ot->srna, "author", nullptr, 0, "Author", "");
523 RNA_def_string(ot->srna, "description", nullptr, 0, "Description", "");
524}
525
527{
528 Main *bmain = CTX_data_main(C);
530 Brush *brush = BKE_paint_brush(paint);
531 BLI_assert(ID_IS_ASSET(&brush->id));
532 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
534 *C, brush_weak_ref, op->reports);
535 if (!asset) {
536 return OPERATOR_CANCELLED;
537 }
538
539 char filepath[FILE_MAX];
540 RNA_string_get(op->ptr, "filepath", filepath);
541 if (!BLI_is_file(filepath)) {
542 BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", filepath);
543 return OPERATOR_CANCELLED;
544 }
545
546 BKE_previewimg_id_custom_set(&brush->id, filepath);
547
548 if (!bke::asset_edit_id_save(*bmain, brush->id, *op->reports)) {
549 return OPERATOR_CANCELLED;
550 }
551
554
555 return OPERATOR_FINISHED;
556}
557
559 wmOperator *op,
560 const wmEvent *event)
561{
562 if (RNA_struct_property_is_set(op->ptr, "filepath")) {
564 }
565 return WM_operator_filesel(C, op, event);
566}
567
569{
570 ot->name = "Load Preview Image";
571 ot->description = "Choose a preview image for the brush";
572 ot->idname = "BRUSH_OT_asset_load_preview";
573
577
585}
586
588{
590 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
591 if (paint == nullptr || brush == nullptr) {
592 return false;
593 }
594
595 /* Linked brush, check if belongs to an editable blend file. */
596 if (ID_IS_LINKED(brush)) {
597 if (!bke::asset_edit_id_is_writable(brush->id)) {
598 CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable");
599 return false;
600 }
601 }
602
603 return true;
604}
605
607{
609 Brush *brush = BKE_paint_brush(paint);
610 Main *bmain = CTX_data_main(C);
611 bUserAssetLibrary *library = (paint->brush_asset_reference) ?
613 &U,
614 paint->brush_asset_reference->asset_library_identifier) :
615 nullptr;
616
617 bke::asset_edit_id_delete(*bmain, brush->id, *op->reports);
618
620
621 if (library) {
623 }
624
627
628 return OPERATOR_FINISHED;
629}
630
632 wmOperator *op,
633 const wmEvent * /*event*/)
634{
636 Brush *brush = BKE_paint_brush(paint);
637
639 C,
640 op,
641 IFACE_("Delete Brush Asset"),
642 ID_IS_LINKED(brush) ?
643 IFACE_("Permanently delete brush asset blend file. This cannot be undone.") :
644 IFACE_("Permanently delete brush. This cannot be undone."),
645 IFACE_("Delete"),
647 false);
648}
649
651{
652 ot->name = "Delete Brush Asset";
653 ot->description = "Delete the active brush asset";
654 ot->idname = "BRUSH_OT_asset_delete";
655
659}
660
661static std::optional<AssetLibraryReference> get_asset_library_reference(const bContext &C,
662 const Paint &paint,
663 const Brush &brush)
664{
665 if (!ID_IS_ASSET(&brush.id)) {
667 return std::nullopt;
668 }
669 const AssetWeakReference *brush_weak_ref = paint.brush_asset_reference;
670 if (!brush_weak_ref) {
672 return std::nullopt;
673 }
675 C, *brush_weak_ref, CTX_wm_reports(&C));
676 if (!asset) {
677 /* May happen if library loading hasn't finished. */
678 return std::nullopt;
679 }
680 return asset->owner_asset_library().library_reference();
681}
682
684{
686 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
687 if (paint == nullptr || brush == nullptr) {
688 return false;
689 }
690
691 const std::optional<AssetLibraryReference> library_ref = get_asset_library_reference(
692 *C, *paint, *brush);
693 if (!library_ref) {
695 return false;
696 }
697
698 if (library_ref->type == ASSET_LIBRARY_LOCAL) {
699 CTX_wm_operator_poll_msg_set(C, "Assets in the current file cannot be individually saved");
700 return false;
701 }
702
703 if (!bke::asset_edit_id_is_writable(brush->id)) {
704 CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable");
705 return false;
706 }
707
708 return true;
709}
710
712{
713 Main *bmain = CTX_data_main(C);
715 Brush *brush = BKE_paint_brush(paint);
716 const AssetWeakReference *asset_weak_ref = paint->brush_asset_reference;
717
719 &U, asset_weak_ref->asset_library_identifier);
720 if (!user_library) {
721 return OPERATOR_CANCELLED;
722 }
723
724 BLI_assert(ID_IS_ASSET(brush));
725
726 bke::asset_edit_id_save(*bmain, brush->id, *op->reports);
727 brush->has_unsaved_changes = false;
728
729 asset::refresh_asset_library(C, *user_library);
732
733 return OPERATOR_FINISHED;
734}
735
737{
738 ot->name = "Save Brush Asset";
739 ot->description = "Update the active brush asset in the asset library with current settings";
740 ot->idname = "BRUSH_OT_asset_save";
741
744}
745
747{
749 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
750 if (paint == nullptr || brush == nullptr) {
751 return false;
752 }
753
754 const std::optional<AssetLibraryReference> library_ref = get_asset_library_reference(
755 *C, *paint, *brush);
756 if (!library_ref) {
758 return false;
759 }
760 if (library_ref->type == ASSET_LIBRARY_LOCAL) {
761 CTX_wm_operator_poll_msg_set(C, "Assets in the current file cannot be reverted");
762 return false;
763 }
764
765 return bke::asset_edit_id_is_editable(brush->id);
766}
767
769{
770 Main *bmain = CTX_data_main(C);
772 Brush *brush = BKE_paint_brush(paint);
773
774 if (ID *reverted_id = bke::asset_edit_id_revert(*bmain, brush->id, *op->reports)) {
775 BLI_assert(GS(reverted_id->name) == ID_BR);
776 BKE_paint_brush_set(paint, reinterpret_cast<Brush *>(reverted_id));
777 }
778 else {
779 /* bke::asset_edit_id_revert() deleted the brush for sure, even on failure. Fall back to the
780 * default. */
782 }
783
786
787 return OPERATOR_FINISHED;
788}
789
791{
792 ot->name = "Revert Brush Asset";
793 ot->description =
794 "Revert the active brush settings to the default values from the asset library";
795 ot->idname = "BRUSH_OT_asset_revert";
796
799}
800
801} // namespace blender::ed::sculpt_paint
blender::asset_system::AssetLibrary * AS_asset_library_load(const Main *bmain, const AssetLibraryReference &library_reference)
Main runtime representation of an asset.
AssetMetaData * BKE_asset_metadata_copy(const AssetMetaData *source)
Definition asset.cc:44
void BKE_asset_metadata_free(AssetMetaData **asset_data)
Definition asset.cc:38
void BKE_asset_metadata_catalog_id_set(AssetMetaData *asset_data, bUUID catalog_id, const char *catalog_simple_name)
Brush * BKE_brush_duplicate(Main *bmain, Brush *brush, eDupli_ID_Flags dupflag, uint duplicate_options)
Definition brush.cc:690
ReportList * CTX_wm_reports(const bContext *C)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
Main * CTX_data_main(const bContext *C)
IDNewNameResult BKE_libblock_rename(Main &bmain, ID &id, blender::StringRefNull name, const IDNewNameMode mode=IDNewNameMode::RenameExistingNever)
Definition lib_id.cc:2370
@ LIB_ID_DUPLICATE_IS_ROOT_ID
bool BKE_paint_brush_set(Paint *paint, Brush *brush)
Definition paint.cc:710
void BKE_paint_previous_asset_reference_set(Paint *paint, AssetWeakReference &&asset_weak_reference)
Definition paint.cc:1111
void BKE_paint_previous_asset_reference_clear(Paint *paint)
Definition paint.cc:1120
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:476
bool BKE_paint_brush_set_default(Main *bmain, Paint *paint)
Definition paint.cc:1099
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:645
struct bUserAssetLibrary * BKE_preferences_asset_library_find_by_name(const struct UserDef *userdef, const char *name) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
void BKE_previewimg_id_custom_set(ID *id, const char *filepath)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_ERROR
Definition BKE_report.hh:39
@ RPT_WARNING
Definition BKE_report.hh:38
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
File and directory operations.
bool BLI_is_file(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:448
#define FILE_MAX
#define STRNCPY_UTF8(dst, src)
#define IFACE_(msgid)
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
#define ID_IS_ASSET(_id)
Definition DNA_ID.h:737
@ ID_BR
eAssetLibraryType
@ ASSET_LIBRARY_ESSENTIALS
@ ASSET_LIBRARY_LOCAL
#define MAX_NAME
Definition DNA_defs.h:50
@ FILE_SORT_DEFAULT
@ FILE_SPECIAL
@ FILE_TYPE_FOLDER
@ FILE_TYPE_IMAGE
@ FILE_DEFAULTDISPLAY
@ USER_DUP_LINKED_ID
@ USER_DUP_OBDATA
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
#define MEM_SAFE_FREE(v)
@ PROP_STRING_SEARCH_SUGGESTION
Definition RNA_types.hh:792
@ PROP_ENUM
Definition RNA_types.hh:166
PropertyFlag
Definition RNA_types.hh:300
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
@ PROP_HIDDEN
Definition RNA_types.hh:338
@ PROP_NONE
Definition RNA_types.hh:233
#define C
Definition RandGen.cpp:29
@ ALERT_ICON_WARNING
@ WM_FILESEL_FILEPATH
Definition WM_api.hh:1124
@ FILE_OPENFILE
Definition WM_api.hh:1133
#define NA_ACTIVATED
Definition WM_types.hh:590
#define NC_BRUSH
Definition WM_types.hh:385
#define NC_SCENE
Definition WM_types.hh:378
#define NA_ADDED
Definition WM_types.hh:586
#define ND_NODES
Definition WM_types.hh:436
#define ND_TOOLSETTINGS
Definition WM_types.hh:449
#define NA_EDITED
Definition WM_types.hh:584
#define NC_ASSET
Definition WM_types.hh:404
#define NA_REMOVED
Definition WM_types.hh:587
#define NC_TEXTURE
Definition WM_types.hh:381
#define ND_ASSET_LIST
Definition WM_types.hh:548
#define U
AssetCatalog * find_catalog(CatalogID catalog_id) const
bool write_to_disk(const CatalogFilePath &blend_file_path)
AssetCatalogService & catalog_service() const
virtual std::optional< AssetLibraryReference > library_reference() const =0
#define GS(x)
#define G(x, y, z)
AssetLibraryReference all_library_reference()
AssetLibraryReference current_file_library_reference()
ID * asset_edit_id_from_weak_reference(Main &global_main, ID_Type id_type, const AssetWeakReference &weak_ref)
std::optional< std::string > asset_edit_id_save_as(Main &global_main, const ID &id, StringRefNull name, const bUserAssetLibrary &user_library, AssetWeakReference &r_weak_ref, ReportList &reports)
ID * asset_edit_id_revert(Main &global_main, ID &id, ReportList &reports)
bool asset_edit_id_delete(Main &global_main, ID &id, ReportList &reports)
bool asset_edit_id_is_writable(const ID &id)
bool asset_edit_id_is_editable(const ID &id)
bool asset_edit_id_save(Main &global_main, const ID &id, ReportList &reports)
void storage_fetch_blocking(const AssetLibraryReference &library_reference, const bContext &C)
void show_catalog_in_visible_shelves(const bContext &C, const StringRefNull catalog_path)
const asset_system::AssetRepresentation * find_asset_from_weak_ref(const bContext &C, const AssetWeakReference &weak_ref, ReportList *reports)
AssetLibraryReference get_asset_library_ref_from_opptr(PointerRNA &ptr)
int library_reference_to_enum_value(const AssetLibraryReference *library)
const EnumPropertyItem * library_reference_to_rna_enum_itemf(bool include_readonly, bool include_current_file)
void refresh_asset_library(const bContext *C, const AssetLibraryReference &library_ref)
void operator_asset_reference_props_register(StructRNA &srna)
void catalogs_save_from_asset_reference(asset_system::AssetLibrary &library, const AssetWeakReference &reference)
void generate_preview(const bContext *C, ID *id)
const asset_system::AssetRepresentation * operator_asset_reference_props_get_asset_from_all_library(const bContext &C, PointerRNA &ptr, ReportList *reports)
void visit_library_catalogs_catalog_for_search(const Main &bmain, const AssetLibraryReference lib, const StringRef edit_text, const FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
const bUserAssetLibrary * get_asset_library_from_opptr(PointerRNA &ptr)
void refresh_asset_library_from_asset(const bContext *C, const blender::asset_system::AssetRepresentation &asset)
AssetLibraryReference user_library_to_library_ref(const bUserAssetLibrary &user_library)
blender::asset_system::AssetCatalog & library_ensure_catalogs_in_path(blender::asset_system::AssetLibrary &library, const blender::asset_system::AssetCatalogPath &path)
void BRUSH_OT_asset_save(wmOperatorType *ot)
static bool brush_asset_edit_metadata_poll(bContext *C)
static std::optional< AssetLibraryReference > get_asset_library_reference(const bContext &C, const Paint &paint, const Brush &brush)
void BRUSH_OT_asset_delete(wmOperatorType *ot)
static wmOperatorStatus brush_asset_save_as_exec(bContext *C, wmOperator *op)
void BRUSH_OT_asset_edit_metadata(wmOperatorType *ot)
static bool brush_asset_delete_poll(bContext *C)
static void visit_library_prop_catalogs_catalog_for_search_fn(const bContext *C, PointerRNA *ptr, PropertyRNA *, const char *edit_text, FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
static wmOperatorStatus brush_asset_revert_exec(bContext *C, wmOperator *op)
static bool library_is_editable(const AssetLibraryReference &library)
static void visit_active_library_catalogs_catalog_for_search_fn(const bContext *C, PointerRNA *, PropertyRNA *, const char *edit_text, FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
static wmOperatorStatus brush_asset_load_preview_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void BRUSH_OT_asset_load_preview(wmOperatorType *ot)
static wmOperatorStatus brush_asset_delete_invoke(bContext *C, wmOperator *op, const wmEvent *)
static bool brush_asset_save_as_poll(bContext *C)
static wmOperatorStatus brush_asset_delete_exec(bContext *C, wmOperator *op)
static bool brush_asset_revert_poll(bContext *C)
static wmOperatorStatus brush_asset_load_preview_exec(bContext *C, wmOperator *op)
static wmOperatorStatus brush_asset_activate_exec(bContext *C, wmOperator *op)
static wmOperatorStatus brush_asset_edit_metadata_exec(bContext *C, wmOperator *op)
static wmOperatorStatus brush_asset_edit_metadata_invoke(bContext *C, wmOperator *op, const wmEvent *)
void BRUSH_OT_asset_revert(wmOperatorType *ot)
static bool brush_asset_save_poll(bContext *C)
void BRUSH_OT_asset_save_as(wmOperatorType *ot)
static wmOperatorStatus brush_asset_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *)
static const EnumPropertyItem * rna_asset_library_reference_itemf(bContext *, PointerRNA *, PropertyRNA *, bool *r_free)
void BRUSH_OT_asset_activate(wmOperatorType *ot)
static wmOperatorStatus brush_asset_save_exec(bContext *C, wmOperator *op)
const char * name
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
std::string RNA_string_get(PointerRNA *ptr, const char *name)
std::string RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_string_search_func_runtime(PropertyRNA *prop, StringPropertySearchFunc search_fn, const eStringPropertySearchFlag search_flag)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
The meta-data of an asset. By creating and giving this for a data-block (ID.asset_data),...
struct bUUID catalog_id
const char * asset_library_identifier
char has_unsaved_changes
Definition DNA_ID.h:414
struct AssetMetaData * asset_data
Definition DNA_ID.h:423
char name[258]
Definition DNA_ID.h:432
int us
Definition DNA_ID.h:443
struct ReportList * reports
struct PointerRNA * ptr
void WM_main_add_notifier(uint type, void *reference)
void WM_file_tag_modified()
Definition wm_files.cc:177
PointerRNA * ptr
Definition wm_files.cc:4238
wmOperatorType * ot
Definition wm_files.cc:4237
void WM_operator_properties_filesel(wmOperatorType *ot, const int filter, const short type, const eFileSel_Action action, const eFileSel_Flag flag, const short display, const short sort)
wmOperatorStatus WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default, std::optional< std::string > message)
wmOperatorStatus WM_operator_confirm_ex(bContext *C, wmOperator *op, const char *title, const char *message, const char *confirm_text, int icon, bool cancel_default)
wmOperatorStatus WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *)
bool WM_toolsystem_activate_brush_and_tool(bContext *C, Paint *paint, Brush *brush)