Blender V4.3
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_path_utils.hh"
7#include "BLI_string.h"
8
9#include "DNA_brush_types.h"
10#include "DNA_scene_types.h"
11#include "DNA_space_types.h"
12#include "DNA_workspace_types.h"
13
14#include "BKE_asset.hh"
15#include "BKE_asset_edit.hh"
16#include "BKE_blendfile.hh"
17#include "BKE_brush.hh"
18#include "BKE_context.hh"
19#include "BKE_paint.hh"
20#include "BKE_preferences.h"
21#include "BKE_preview_image.hh"
22#include "BKE_report.hh"
23
26#include "AS_asset_library.hh"
28
29#include "RNA_access.hh"
30#include "RNA_define.hh"
31
32#include "ED_asset_handle.hh"
33#include "ED_asset_library.hh"
34#include "ED_asset_list.hh"
37#include "ED_asset_shelf.hh"
38
39#include "UI_interface_icons.hh"
40#include "UI_resources.hh"
41
42#include "BLT_translation.hh"
43
44#include "WM_api.hh"
45#include "WM_toolsystem.hh"
46
47#include "paint_intern.hh"
48
50
52{
53 /* This operator currently covers both cases: the file/asset browser file list and the asset list
54 * used for the asset-view template. Once the asset list design is used by the Asset Browser,
55 * this can be simplified to just that case. */
56 Main *bmain = CTX_data_main(C);
59 if (!asset) {
60 return OPERATOR_CANCELLED;
61 }
62
63 AssetWeakReference brush_asset_reference = asset->make_weak_reference();
64 Brush *brush = reinterpret_cast<Brush *>(
65 bke::asset_edit_id_from_weak_reference(*bmain, ID_BR, brush_asset_reference));
66
68
69 /* Activate brush through tool system rather than calling #BKE_paint_brush_set() directly, to let
70 * the tool system switch tools if necessary, and update which brush was the last recently used
71 * one for the current tool. */
72 if (!WM_toolsystem_activate_brush_and_tool(C, paint, brush)) {
73 /* Note brush datablock was still added, so was not a no-op. */
74 BKE_report(op->reports, RPT_WARNING, "Unable to activate brush, wrong object mode");
75 return OPERATOR_FINISHED;
76 }
77
80
81 return OPERATOR_FINISHED;
82}
83
85{
86 ot->name = "Activate Brush Asset";
87 ot->description = "Activate a brush asset as current sculpt and paint tool";
88 ot->idname = "BRUSH_OT_asset_activate";
89
91
93}
94
95static std::optional<AssetLibraryReference> library_to_library_ref(
96 const asset_system::AssetLibrary &library)
97{
99 const std::string root_path = AS_asset_library_root_path_from_library_ref(ref);
100 /* Use #BLI_path_cmp_normalized because `library.root_path()` ends with a slash while
101 * `root_path` doesn't. */
102 if (BLI_path_cmp_normalized(root_path.c_str(), library.root_path().c_str()) == 0) {
103 return ref;
104 }
105 }
106 return std::nullopt;
107}
108
110{
111 AssetLibraryReference library_ref{};
112 library_ref.custom_library_index = BLI_findindex(&U.asset_libraries, &user_library);
113 library_ref.type = ASSET_LIBRARY_CUSTOM;
114 return library_ref;
115}
116
118 const AssetLibraryReference &library_ref)
119{
120 if (library_ref.type != ASSET_LIBRARY_CUSTOM) {
121 return nullptr;
122 }
123 return static_cast<const bUserAssetLibrary *>(
124 BLI_findlink(&U.asset_libraries, library_ref.custom_library_index));
125}
126
127static void refresh_asset_library(const bContext *C, const AssetLibraryReference &library_ref)
128{
129 asset::list::clear(&library_ref, C);
130 /* TODO: Should the all library reference be automatically cleared? */
132 asset::list::clear(&all_lib_ref, C);
133}
134
135static void refresh_asset_library(const bContext *C, const bUserAssetLibrary &user_library)
136{
138}
139
141{
143 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
144 if (paint == nullptr || brush == nullptr) {
145 return false;
146 }
147 if (!paint->brush_asset_reference) {
148 /* The brush should always be an imported asset. We use this asset reference to find
149 * which library and catalog the brush came from, as defaults for the popup. */
150 return false;
151 }
152
153 if (BLI_listbase_is_empty(&U.asset_libraries)) {
154 CTX_wm_operator_poll_msg_set(C, "No asset library available to save to");
155 return false;
156 }
157
158 return true;
159}
160
162{
163 const int enum_value = RNA_enum_get(&ptr, "asset_library_reference");
166}
167
170{
171 if (asset_system::AssetCatalog *catalog = library.catalog_service().find_catalog_by_path(path)) {
172 return *catalog;
173 }
174 return *library.catalog_service().create_catalog(path);
175}
176
177/* Suppress warning for GCC-14.2. This isn't a dangling reference
178 * because the #asset_system::AssetLibrary owns the returned value. */
179#if defined(__GNUC__) && !defined(__clang__)
180# pragma GCC diagnostic push
181# pragma GCC diagnostic ignored "-Wdangling-reference"
182#endif
183
186{
187 /* Adding multiple catalogs in a path at a time with #AssetCatalogService::create_catalog()
188 * doesn't work; add each potentially new catalog in the hierarchy manually here. */
190 path.iterate_components([&](StringRef component_name, bool /*is_last_component*/) {
191 asset_library_ensure_catalog(library, parent / component_name);
192 parent = parent / component_name;
193 });
194 return *library.catalog_service().find_catalog_by_path(path);
195}
196#if defined(__GNUC__) && !defined(__clang__)
197# pragma GCC diagnostic pop
198#endif
199
200static void show_catalog_in_asset_shelf(const bContext &C, const StringRefNull catalog_path)
201{
202 /* Enable catalog in all visible asset shelves. */
204 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
205 const bScreen *screen = WM_window_get_active_screen(win);
206 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
209 &U, shelf->idname, catalog_path.c_str()))
210 {
211 U.runtime.is_dirty = true;
212 }
213 }
214 }
215}
216
218{
219 Main *bmain = CTX_data_main(C);
221 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
222
223 /* Determine file path to save to. */
224 PropertyRNA *name_prop = RNA_struct_find_property(op->ptr, "name");
225 char name[MAX_NAME] = "";
226 if (RNA_property_is_set(op->ptr, name_prop)) {
227 RNA_property_string_get(op->ptr, name_prop, name);
228 }
229 if (name[0] == '\0') {
230 STRNCPY(name, brush->id.name + 2);
231 }
232
233 const bUserAssetLibrary *user_library = get_asset_library_from_prop(*op->ptr);
234 if (!user_library) {
235 return OPERATOR_CANCELLED;
236 }
237
239 bmain, user_library_to_library_ref(*user_library));
240 if (!library) {
241 BKE_report(op->reports, RPT_ERROR, "Failed to load asset library");
242 return OPERATOR_CANCELLED;
243 }
244
245 /* Turn brush into asset if it isn't yet. */
246 if (!ID_IS_ASSET(&brush->id)) {
247 asset::mark_id(&brush->id);
248 asset::generate_preview(C, &brush->id);
249 }
250 BLI_assert(ID_IS_ASSET(&brush->id));
251
252 /* Add asset to catalog. */
253 char catalog_path[MAX_NAME];
254 RNA_string_get(op->ptr, "catalog_path", catalog_path);
255
256 AssetMetaData &meta_data = *brush->id.asset_data;
257 if (catalog_path[0]) {
259 *library, catalog_path);
260 BKE_asset_metadata_catalog_id_set(&meta_data, catalog.catalog_id, catalog.simple_name.c_str());
261 }
262
263 AssetWeakReference brush_asset_reference;
264 const std::optional<std::string> final_full_asset_filepath = bke::asset_edit_id_save_as(
265 *bmain, brush->id, name, *user_library, brush_asset_reference, *op->reports);
266 if (!final_full_asset_filepath) {
267 return OPERATOR_CANCELLED;
268 }
269
270 library->catalog_service().write_to_disk(*final_full_asset_filepath);
271 show_catalog_in_asset_shelf(*C, catalog_path);
272
273 brush = reinterpret_cast<Brush *>(
274 bke::asset_edit_id_from_weak_reference(*bmain, ID_BR, brush_asset_reference));
275 brush->has_unsaved_changes = false;
276
277 if (!WM_toolsystem_activate_brush_and_tool(C, paint, brush)) {
278 /* Note brush asset was still saved in editable asset library, so was not a no-op. */
279 BKE_report(op->reports, RPT_WARNING, "Unable to activate just-saved brush asset");
280 }
281
282 refresh_asset_library(C, *user_library);
285
286 return OPERATOR_FINISHED;
287}
288
290{
291 if (library.type == ASSET_LIBRARY_ESSENTIALS) {
292 return false;
293 }
294 return true;
295}
296
297static int brush_asset_save_as_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
298{
300 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
302 *C, brush_weak_ref, op->reports);
303 if (!asset) {
304 return OPERATOR_CANCELLED;
305 }
306 const asset_system::AssetLibrary &library = asset->owner_asset_library();
307 const std::optional<AssetLibraryReference> library_ref = library_to_library_ref(library);
308 if (!library_ref) {
310 return OPERATOR_CANCELLED;
311 }
312
313 RNA_string_set(op->ptr, "name", asset->get_name().c_str());
314
315 /* If the library isn't saved from the operator's last execution, find the current library or the
316 * first library if the current library isn't editable. */
317 if (!RNA_struct_property_is_set_ex(op->ptr, "asset_library_reference", false)) {
318 if (library_is_editable(*library_ref)) {
319 RNA_enum_set(op->ptr,
320 "asset_library_reference",
322 }
323 else {
325 *static_cast<const bUserAssetLibrary *>(U.asset_libraries.first));
326 RNA_enum_set(op->ptr,
327 "asset_library_reference",
329 }
330 }
331
332 /* By default, put the new asset in the same catalog as the existing asset. */
333 if (!RNA_struct_property_is_set(op->ptr, "catalog_path")) {
335 if (const asset_system::AssetCatalog *catalog = library.catalog_service().find_catalog(id)) {
336 RNA_string_set(op->ptr, "catalog_path", catalog->path.c_str());
337 }
338 }
339
340 return WM_operator_props_dialog_popup(C, op, 400, std::nullopt, IFACE_("Save"));
341}
342
344 PointerRNA * /*ptr*/,
345 PropertyRNA * /*prop*/,
346 bool *r_free)
347{
349 if (!items) {
350 *r_free = false;
351 return nullptr;
352 }
353
354 *r_free = true;
355 return items;
356}
357
359 const Main &bmain,
360 const bUserAssetLibrary &user_library,
361 const StringRef edit_text,
362 const FunctionRef<void(StringPropertySearchVisitParams)> visit_fn)
363{
365 &bmain, user_library_to_library_ref(user_library));
366 if (!library) {
367 return;
368 }
369
370 if (!edit_text.is_empty()) {
371 const asset_system::AssetCatalogPath edit_path = edit_text;
372 if (!library->catalog_service().find_catalog_by_path(edit_path)) {
373 visit_fn(StringPropertySearchVisitParams{edit_path.str(), std::nullopt, ICON_ADD});
374 }
375 }
376
377 const asset_system::AssetCatalogTree &full_tree = library->catalog_service().catalog_tree();
378 full_tree.foreach_item([&](const asset_system::AssetCatalogTreeItem &item) {
379 visit_fn(StringPropertySearchVisitParams{item.catalog_path().str(), std::nullopt});
380 });
381}
382
384 const bContext *C,
386 PropertyRNA * /*prop*/,
387 const char *edit_text,
389{
390 /* NOTE: Using the all library would also be a valid choice. */
391 if (const bUserAssetLibrary *user_library = get_asset_library_from_prop(*ptr)) {
393 *CTX_data_main(C), *user_library, edit_text, visit_fn);
394 }
395}
396
398{
399 ot->name = "Save as Brush Asset";
400 ot->description =
401 "Save a copy of the active brush asset into the default asset library, and make it the "
402 "active brush";
403 ot->idname = "BRUSH_OT_asset_save_as";
404
408
410 ot->srna, "name", nullptr, MAX_NAME, "Name", "Name for the new brush asset");
411
412 PropertyRNA *prop = RNA_def_property(ot->srna, "asset_library_reference", PROP_ENUM, PROP_NONE);
414 RNA_def_property_ui_text(prop, "Library", "Asset library used to store the new brush");
415
416 prop = RNA_def_string(
417 ot->srna, "catalog_path", nullptr, MAX_NAME, "Catalog", "Catalog to use for the new asset");
420}
421
423{
424 Main *bmain = CTX_data_main(C);
426 Brush *brush = BKE_paint_brush(paint);
427 BLI_assert(ID_IS_ASSET(&brush->id));
428 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
430 *C, brush_weak_ref, op->reports);
431 if (!asset) {
432 return OPERATOR_CANCELLED;
433 }
434 const asset_system::AssetLibrary &library_const = asset->owner_asset_library();
435 const AssetLibraryReference library_ref = *library_to_library_ref(library_const);
436 asset_system::AssetLibrary *library = AS_asset_library_load(bmain, library_ref);
437
438 char catalog_path[MAX_NAME];
439 RNA_string_get(op->ptr, "catalog_path", catalog_path);
440
441 AssetMetaData &meta_data = *brush->id.asset_data;
442 MEM_SAFE_FREE(meta_data.author);
443 meta_data.author = RNA_string_get_alloc(op->ptr, "author", nullptr, 0, nullptr);
444 MEM_SAFE_FREE(meta_data.description);
445 meta_data.description = RNA_string_get_alloc(op->ptr, "description", nullptr, 0, nullptr);
446
447 if (catalog_path[0]) {
449 *library, catalog_path);
450 BKE_asset_metadata_catalog_id_set(&meta_data, catalog.catalog_id, catalog.simple_name.c_str());
451 }
452
453 if (!bke::asset_edit_id_save(*bmain, brush->id, *op->reports)) {
454 return OPERATOR_CANCELLED;
455 }
456
457 char asset_full_path_buffer[FILE_MAX_LIBEXTRA];
458 char *file_path = nullptr;
460 &brush_weak_ref, asset_full_path_buffer, &file_path, nullptr, nullptr);
461 if (!file_path) {
463 return OPERATOR_CANCELLED;
464 }
465
466 library->catalog_service().write_to_disk(file_path);
467
468 refresh_asset_library(C, library_ref);
470
471 return OPERATOR_FINISHED;
472}
473
474static int brush_asset_edit_metadata_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
475{
477 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
479 *C, brush_weak_ref, op->reports);
480 if (!asset) {
481 return OPERATOR_CANCELLED;
482 }
483 const asset_system::AssetLibrary &library = asset->owner_asset_library();
484 const AssetMetaData &meta_data = asset->get_metadata();
485
486 if (!RNA_struct_property_is_set(op->ptr, "catalog_path")) {
487 const asset_system::CatalogID &id = meta_data.catalog_id;
488 if (const asset_system::AssetCatalog *catalog = library.catalog_service().find_catalog(id)) {
489 RNA_string_set(op->ptr, "catalog_path", catalog->path.c_str());
490 }
491 }
492 if (!RNA_struct_property_is_set(op->ptr, "author")) {
493 RNA_string_set(op->ptr, "author", meta_data.author ? meta_data.author : "");
494 }
495 if (!RNA_struct_property_is_set(op->ptr, "description")) {
496 RNA_string_set(op->ptr, "description", meta_data.description ? meta_data.description : "");
497 }
498
499 return WM_operator_props_dialog_popup(C, op, 400, std::nullopt, IFACE_("Edit Metadata"));
500}
501
503 const bContext *C,
504 PointerRNA * /*ptr*/,
505 PropertyRNA * /*prop*/,
506 const char *edit_text,
508{
510 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
512 *C, brush_weak_ref, nullptr);
513 if (!asset) {
514 return;
515 }
516 const asset_system::AssetLibrary &library = asset->owner_asset_library();
517
518 /* NOTE: Using the all library would also be a valid choice. */
520 *CTX_data_main(C),
522 edit_text,
523 visit_fn);
524}
525
527{
529 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
530 if (paint == nullptr || brush == nullptr) {
531 return false;
532 }
533 if (!ID_IS_ASSET(&brush->id)) {
535 return false;
536 }
537 const AssetWeakReference *brush_weak_ref = paint->brush_asset_reference;
538 if (!brush_weak_ref) {
540 return false;
541 }
543 *C, *brush_weak_ref, nullptr);
544 if (!asset) {
546 return false;
547 }
548 const std::optional<AssetLibraryReference> library_ref = library_to_library_ref(
549 asset->owner_asset_library());
550 if (!library_ref) {
552 return false;
553 }
554 if (!library_is_editable(*library_ref)) {
555 CTX_wm_operator_poll_msg_set(C, "Asset library is not editable");
556 return false;
557 }
558 if (!bke::asset_edit_id_is_writable(brush->id)) {
559 CTX_wm_operator_poll_msg_set(C, "Asset file is not editable");
560 return false;
561 }
562 return true;
563}
564
566{
567 ot->name = "Edit Metadata";
568 ot->description = "Edit asset information like the catalog, preview image, tags, or author";
569 ot->idname = "BRUSH_OT_asset_edit_metadata";
570
574
576 ot->srna, "catalog_path", nullptr, MAX_NAME, "Catalog", "The asset's catalog path");
579 RNA_def_string(ot->srna, "author", nullptr, MAX_NAME, "Author", "");
580 RNA_def_string(ot->srna, "description", nullptr, MAX_NAME, "Description", "");
581}
582
584{
585 Main *bmain = CTX_data_main(C);
587 Brush *brush = BKE_paint_brush(paint);
588 BLI_assert(ID_IS_ASSET(&brush->id));
589 const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
591 *C, brush_weak_ref, op->reports);
592 if (!asset) {
593 return OPERATOR_CANCELLED;
594 }
596
597 char filepath[FILE_MAX];
598 RNA_string_get(op->ptr, "filepath", filepath);
599 if (!BLI_is_file(filepath)) {
600 BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", filepath);
601 return OPERATOR_CANCELLED;
602 }
603
604 BKE_previewimg_id_custom_set(&brush->id, filepath);
605
606 if (!bke::asset_edit_id_save(*bmain, brush->id, *op->reports)) {
607 return OPERATOR_CANCELLED;
608 }
609
610 refresh_asset_library(C, library_ref);
612
613 return OPERATOR_FINISHED;
614}
615
617{
618 if (RNA_struct_property_is_set(op->ptr, "filepath")) {
619 return brush_asset_load_preview_exec(C, op);
620 }
621 return WM_operator_filesel(C, op, event);
622}
623
625{
626 ot->name = "Load Preview Image";
627 ot->description = "Choose a preview image for the brush";
628 ot->idname = "BRUSH_OT_asset_load_preview";
629
633
641}
642
644{
646 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
647 if (paint == nullptr || brush == nullptr) {
648 return false;
649 }
650
651 /* Linked brush, check if belongs to an editable blend file. */
652 if (ID_IS_LINKED(brush)) {
653 if (!bke::asset_edit_id_is_writable(brush->id)) {
654 CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable");
655 return false;
656 }
657 }
658
659 return true;
660}
661
663{
665 Brush *brush = BKE_paint_brush(paint);
666 Main *bmain = CTX_data_main(C);
667 bUserAssetLibrary *library = (paint->brush_asset_reference) ?
669 &U,
671 nullptr;
672
673 bke::asset_edit_id_delete(*bmain, brush->id, *op->reports);
674
675 BKE_paint_brush_set_default(bmain, paint);
676
677 if (library) {
678 refresh_asset_library(C, *library);
679 }
680
683
684 return OPERATOR_FINISHED;
685}
686
687static int brush_asset_delete_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
688{
690 Brush *brush = BKE_paint_brush(paint);
691
693 C,
694 op,
695 IFACE_("Delete Brush Asset"),
696 ID_IS_LINKED(brush) ?
697 IFACE_("Permanently delete brush asset blend file. This cannot be undone.") :
698 IFACE_("Permanently delete brush. This cannot be undone."),
699 IFACE_("Delete"),
701 false);
702}
703
705{
706 ot->name = "Delete Brush Asset";
707 ot->description = "Delete the active brush asset";
708 ot->idname = "BRUSH_OT_asset_delete";
709
713}
714
716{
718 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
719 if (paint == nullptr || brush == nullptr) {
720 return false;
721 }
722
723 if (!bke::asset_edit_id_is_editable(brush->id)) {
724 return false;
725 }
726
727 if (!(paint->brush_asset_reference && ID_IS_ASSET(brush))) {
728 return false;
729 }
730
731 if (!bke::asset_edit_id_is_writable(brush->id)) {
732 CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable");
733 return false;
734 }
735
736 return true;
737}
738
740{
741 Main *bmain = CTX_data_main(C);
743 Brush *brush = BKE_paint_brush(paint);
744 const AssetWeakReference *asset_weak_ref = paint->brush_asset_reference;
745
747 &U, asset_weak_ref->asset_library_identifier);
748 if (!user_library) {
749 return OPERATOR_CANCELLED;
750 }
751
752 BLI_assert(ID_IS_ASSET(brush));
753
754 bke::asset_edit_id_save(*bmain, brush->id, *op->reports);
755 brush->has_unsaved_changes = false;
756
757 refresh_asset_library(C, *user_library);
760
761 return OPERATOR_FINISHED;
762}
763
765{
766 ot->name = "Save Brush Asset";
767 ot->description = "Update the active brush asset in the asset library with current settings";
768 ot->idname = "BRUSH_OT_asset_save";
769
772}
773
775{
777 Brush *brush = (paint) ? BKE_paint_brush(paint) : nullptr;
778 if (paint == nullptr || brush == nullptr) {
779 return false;
780 }
781
783}
784
786{
787 Main *bmain = CTX_data_main(C);
789 Brush *brush = BKE_paint_brush(paint);
790
791 if (ID *reverted_id = bke::asset_edit_id_revert(*bmain, brush->id, *op->reports)) {
792 BLI_assert(GS(reverted_id->name) == ID_BR);
793 BKE_paint_brush_set(paint, reinterpret_cast<Brush *>(reverted_id));
794 }
795 else {
796 /* bke::asset_edit_id_revert() deleted the brush for sure, even on failure. Fallback to the
797 * default. */
798 BKE_paint_brush_set_default(bmain, paint);
799 }
800
803
804 return OPERATOR_FINISHED;
805}
806
808{
809 ot->name = "Revert Brush Asset";
810 ot->description =
811 "Revert the active brush settings to the default values from the asset library";
812 ot->idname = "BRUSH_OT_asset_revert";
813
816}
817
818} // namespace blender::ed::sculpt_paint
blender::asset_system::AssetLibrary * AS_asset_library_load(const Main *bmain, const AssetLibraryReference &library_reference)
std::string AS_asset_library_root_path_from_library_ref(const AssetLibraryReference &library_reference)
void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_reference, char r_path_buffer[1090], char **r_dir, char **r_group, char **r_name)
Main runtime representation of an asset.
void BKE_asset_metadata_catalog_id_set(AssetMetaData *asset_data, bUUID catalog_id, const char *catalog_simple_name)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
bool BKE_paint_brush_set(Paint *paint, Brush *brush)
Definition paint.cc:714
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:477
bool BKE_paint_brush_set_default(Main *bmain, Paint *paint)
Definition paint.cc:1096
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:649
struct bUserAssetLibrary * BKE_preferences_asset_library_find_index(const struct UserDef *userdef, int index) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
struct bUserAssetLibrary * BKE_preferences_asset_library_find_by_name(const struct UserDef *userdef, const char *name) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
bool BKE_preferences_asset_shelf_settings_ensure_catalog_path_enabled(UserDef *userdef, const char *shelf_idname, const char *catalog_path)
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
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
File and directory operations.
bool BLI_is_file(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:438
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define FILE_MAX
int BLI_path_cmp_normalized(const char *p1, const char *p2) ATTR_NONNULL(1
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define IFACE_(msgid)
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:654
#define ID_IS_ASSET(_id)
Definition DNA_ID.h:690
@ ID_BR
@ ASSET_LIBRARY_CUSTOM
@ ASSET_LIBRARY_ESSENTIALS
#define MAX_NAME
Definition DNA_defs.h:50
@ FILE_SORT_DEFAULT
@ FILE_SPECIAL
@ FILE_TYPE_FOLDER
@ FILE_TYPE_IMAGE
@ FILE_DEFAULTDISPLAY
#define FILE_MAX_LIBEXTRA
#define MEM_SAFE_FREE(v)
@ PROP_STRING_SEARCH_SUGGESTION
Definition RNA_types.hh:584
@ PROP_ENUM
Definition RNA_types.hh:69
@ PROP_NONE
Definition RNA_types.hh:136
@ ALERT_ICON_WARNING
@ WM_FILESEL_FILEPATH
Definition WM_api.hh:936
@ FILE_OPENFILE
Definition WM_api.hh:945
#define NA_ACTIVATED
Definition WM_types.hh:556
#define NC_BRUSH
Definition WM_types.hh:352
#define NC_SCENE
Definition WM_types.hh:345
#define NA_ADDED
Definition WM_types.hh:552
#define ND_NODES
Definition WM_types.hh:403
#define ND_TOOLSETTINGS
Definition WM_types.hh:416
#define NA_EDITED
Definition WM_types.hh:550
#define NC_ASSET
Definition WM_types.hh:371
#define NA_REMOVED
Definition WM_types.hh:553
#define NC_TEXTURE
Definition WM_types.hh:348
#define ND_ASSET_LIST
Definition WM_types.hh:514
unsigned int U
Definition btGjkEpa3.h:78
constexpr bool is_empty() const
constexpr const char * c_str() const
void iterate_components(ComponentIteratorFn callback) const
AssetCatalog * find_catalog_by_path(const AssetCatalogPath &path) const
AssetCatalog * find_catalog(CatalogID catalog_id) const
bool write_to_disk(const CatalogFilePath &blend_file_path)
AssetCatalog * create_catalog(const AssetCatalogPath &catalog_path)
void foreach_item(ItemIterFn callback) const
AssetCatalogService & catalog_service() const
#define str(s)
#define GS(x)
Definition iris.cc:202
AssetLibraryReference all_library_reference()
Vector< AssetLibraryReference > all_valid_asset_library_refs()
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 clear(const AssetLibraryReference *library_reference, const bContext *C)
AssetShelf * active_shelf_from_area(const ScrArea *area)
const asset_system::AssetRepresentation * find_asset_from_weak_ref(const bContext &C, const AssetWeakReference &weak_ref, ReportList *reports)
int library_reference_to_enum_value(const AssetLibraryReference *library)
AssetLibraryReference library_reference_from_enum_value(int value)
void operator_asset_reference_props_register(StructRNA &srna)
const EnumPropertyItem * library_reference_to_rna_enum_itemf(bool include_generated)
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)
static const bUserAssetLibrary * get_asset_library_from_prop(PointerRNA &ptr)
static int brush_asset_edit_metadata_exec(bContext *C, wmOperator *op)
static int brush_asset_edit_metadata_invoke(bContext *C, wmOperator *op, const wmEvent *)
static std::optional< AssetLibraryReference > library_to_library_ref(const asset_system::AssetLibrary &library)
void BRUSH_OT_asset_save(wmOperatorType *ot)
static int brush_asset_delete_exec(bContext *C, wmOperator *op)
static bool brush_asset_edit_metadata_poll(bContext *C)
void BRUSH_OT_asset_delete(wmOperatorType *ot)
void BRUSH_OT_asset_edit_metadata(wmOperatorType *ot)
static asset_system::AssetCatalog & asset_library_ensure_catalogs_in_path(asset_system::AssetLibrary &library, const asset_system::AssetCatalogPath &path)
static bool brush_asset_delete_poll(bContext *C)
static void refresh_asset_library(const bContext *C, const AssetLibraryReference &library_ref)
static asset_system::AssetCatalog & asset_library_ensure_catalog(asset_system::AssetLibrary &library, const asset_system::AssetCatalogPath &path)
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 int brush_asset_delete_invoke(bContext *C, wmOperator *op, const wmEvent *)
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 int brush_asset_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *)
static int brush_asset_load_preview_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void BRUSH_OT_asset_load_preview(wmOperatorType *ot)
static void show_catalog_in_asset_shelf(const bContext &C, const StringRefNull catalog_path)
static bool brush_asset_save_as_poll(bContext *C)
static bool brush_asset_revert_poll(bContext *C)
static int brush_asset_load_preview_exec(bContext *C, wmOperator *op)
static int brush_asset_save_exec(bContext *C, wmOperator *op)
static int brush_asset_activate_exec(bContext *C, wmOperator *op)
void BRUSH_OT_asset_revert(wmOperatorType *ot)
static bool brush_asset_save_poll(bContext *C)
static const bUserAssetLibrary * library_ref_to_user_library(const AssetLibraryReference &library_ref)
static AssetLibraryReference user_library_to_library_ref(const bUserAssetLibrary &user_library)
void BRUSH_OT_asset_save_as(wmOperatorType *ot)
static int brush_asset_revert_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem * rna_asset_library_reference_itemf(bContext *, PointerRNA *, PropertyRNA *, bool *r_free)
static int brush_asset_save_as_exec(bContext *C, wmOperator *op)
void BRUSH_OT_asset_activate(wmOperatorType *ot)
static void visit_library_catalogs_catalog_for_search(const Main &bmain, const bUserAssetLibrary &user_library, const StringRef edit_text, const FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
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)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
std::string RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
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)
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:413
struct AssetMetaData * asset_data
Definition DNA_ID.h:422
char name[66]
Definition DNA_ID.h:425
struct AssetWeakReference * brush_asset_reference
Universally Unique Identifier according to RFC4122.
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
PropertyRNA * prop
Definition WM_types.hh:1092
StructRNA * srna
Definition WM_types.hh:1080
struct ReportList * reports
struct PointerRNA * ptr
void WM_main_add_notifier(uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperatorType * ot
Definition wm_files.cc:4125
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)
int WM_operator_confirm_ex(bContext *C, wmOperator *op, const char *title, const char *message, const char *confirm_text, int icon, bool cancel_default)
int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *)
int 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)
bool WM_toolsystem_activate_brush_and_tool(bContext *C, Paint *paint, Brush *brush)
bScreen * WM_window_get_active_screen(const wmWindow *win)