WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 381 commits from brush-assets-project into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
12 changed files with 37 additions and 23 deletions
Showing only changes of commit f29e118487 - Show all commits

View File

@ -81,7 +81,11 @@ void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
void BKE_asset_weak_reference_write(BlendWriter *writer, const AssetWeakReference *weak_ref); void BKE_asset_weak_reference_write(BlendWriter *writer, const AssetWeakReference *weak_ref);
void BKE_asset_weak_reference_read(BlendDataReader *reader, AssetWeakReference *weak_ref); void BKE_asset_weak_reference_read(BlendDataReader *reader, AssetWeakReference *weak_ref);
Main *BKE_asset_weak_reference_main(Main *global_main, const ID *id); /**
* Database of assets that are weakly reference by scene data,
* currently used for brush assets and their dependencies.
*/
Main *BKE_asset_weak_reference_main(const ID *id);
void BKE_asset_weak_reference_main_free(); void BKE_asset_weak_reference_main_free();
ID *BKE_asset_weak_reference_ensure(Main &global_main, ID *BKE_asset_weak_reference_ensure(Main &global_main,
ID_Type id_type, ID_Type id_type,

View File

@ -14,7 +14,6 @@
#include "DNA_object_enums.h" #include "DNA_object_enums.h"
enum class PaintMode : int8_t; enum class PaintMode : int8_t;
struct AssetWeakReference;
struct Brush; struct Brush;
struct ImBuf; struct ImBuf;
struct ImagePool; struct ImagePool;

View File

@ -23,8 +23,6 @@
* of IDs in a given Main data-base. * of IDs in a given Main data-base.
*/ */
#include "DNA_ID_enums.h"
#include <optional> #include <optional>
struct BlendFileReadReport; struct BlendFileReadReport;

View File

@ -512,6 +512,15 @@ ListBase *which_libbase(Main *bmain, short type);
*/ */
int set_listbasepointers(Main *main, ListBase *lb[]); int set_listbasepointers(Main *main, ListBase *lb[]);
/**
* Return main database this ID is a member of.
*
* Use this in operator and draw code instead of assuming the main
* in the context owns datablocks. Some datablock can be part of
* main datablocks from asset libraries instead.
*/
Main *BKE_main_from_id(Main *global_main, const ID *id);
#define MAIN_VERSION_FILE_ATLEAST(main, ver, subver) \ #define MAIN_VERSION_FILE_ATLEAST(main, ver, subver) \
((main)->versionfile > (ver) || \ ((main)->versionfile > (ver) || \
((main)->versionfile == (ver) && (main)->subversionfile >= (subver))) ((main)->versionfile == (ver) && (main)->subversionfile >= (subver)))

View File

@ -129,7 +129,7 @@ void BKE_asset_weak_reference_read(BlendDataReader *reader, AssetWeakReference *
BLO_read_data_address(reader, &weak_ref->relative_asset_identifier); BLO_read_data_address(reader, &weak_ref->relative_asset_identifier);
} }
/* Main database for each brush asset blend file. /* Main database for storing assets that are weak referenced.
* *
* This avoids mixing asset datablocks in the regular main, which leads to naming conflicts and * This avoids mixing asset datablocks in the regular main, which leads to naming conflicts and
* confusing user interface. * confusing user interface.
@ -166,11 +166,9 @@ static Vector<AssetWeakReferenceMain> &get_weak_reference_mains()
return mains; return mains;
} }
Main *BKE_asset_weak_reference_main(Main *global_main, const ID *id) Main *BKE_asset_weak_reference_main(const ID *id)
{ {
if (!(id->tag & LIB_TAG_ASSET_MAIN)) { BLI_assert(id->tag & LIB_TAG_ASSET_MAIN);
return global_main;
}
for (const AssetWeakReferenceMain &weak_ref_main : get_weak_reference_mains()) { for (const AssetWeakReferenceMain &weak_ref_main : get_weak_reference_mains()) {
/* TODO: Look into make this whole thing more efficient. */ /* TODO: Look into make this whole thing more efficient. */

View File

@ -24,6 +24,7 @@
#include "DNA_ID.h" #include "DNA_ID.h"
#include "BKE_asset_weak_reference.hh"
#include "BKE_bpath.hh" #include "BKE_bpath.hh"
#include "BKE_global.hh" #include "BKE_global.hh"
#include "BKE_idtype.hh" #include "BKE_idtype.hh"
@ -961,3 +962,8 @@ int set_listbasepointers(Main *bmain, ListBase *lb[/*INDEX_ID_MAX*/])
return (INDEX_ID_MAX - 1); return (INDEX_ID_MAX - 1);
} }
Main *BKE_main_from_id(Main *global_main, const ID *id)
{
return (id->tag & LIB_TAG_ASSET_MAIN) ? BKE_asset_weak_reference_main(id) : global_main;
}

View File

@ -1028,7 +1028,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
break; break;
case UI_ID_LOCAL: case UI_ID_LOCAL:
if (id) { if (id) {
Main *id_main = BKE_asset_weak_reference_main(CTX_data_main(C), id); Main *id_main = BKE_main_from_id(CTX_data_main(C), id);
if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) { if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
template_id_liboverride_hierarchy_make( template_id_liboverride_hierarchy_make(
C, id_main, template_ui, &idptr, &undo_push_label); C, id_main, template_ui, &idptr, &undo_push_label);
@ -1050,7 +1050,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
break; break;
case UI_ID_OVERRIDE: case UI_ID_OVERRIDE:
if (id && ID_IS_OVERRIDE_LIBRARY(id)) { if (id && ID_IS_OVERRIDE_LIBRARY(id)) {
Main *id_main = BKE_asset_weak_reference_main(CTX_data_main(C), id); Main *id_main = BKE_main_from_id(CTX_data_main(C), id);
if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) { if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
template_id_liboverride_hierarchy_make( template_id_liboverride_hierarchy_make(
C, id_main, template_ui, &idptr, &undo_push_label); C, id_main, template_ui, &idptr, &undo_push_label);
@ -1072,7 +1072,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
/* make copy */ /* make copy */
Main *bmain = CTX_data_main(C); Main *bmain = CTX_data_main(C);
Main *id_main = BKE_asset_weak_reference_main(bmain, id); Main *id_main = BKE_main_from_id(bmain, id);
if (do_scene_obj) { if (do_scene_obj) {
Scene *scene = CTX_data_scene(C); Scene *scene = CTX_data_scene(C);
@ -1792,7 +1792,7 @@ static void ui_template_id(uiLayout *layout,
Main *id_main = CTX_data_main(C); Main *id_main = CTX_data_main(C);
if (ptr->owner_id) { if (ptr->owner_id) {
id_main = BKE_asset_weak_reference_main(id_main, ptr->owner_id); id_main = BKE_main_from_id(id_main, ptr->owner_id);
} }
StructRNA *type = RNA_property_pointer_type(ptr, prop); StructRNA *type = RNA_property_pointer_type(ptr, prop);

View File

@ -829,7 +829,7 @@ static int new_texture_exec(bContext *C, wmOperator * /*op*/)
Main *id_main = CTX_data_main(C); Main *id_main = CTX_data_main(C);
if (ptr.owner_id) { if (ptr.owner_id) {
id_main = BKE_asset_weak_reference_main(id_main, ptr.owner_id); id_main = BKE_main_from_id(id_main, ptr.owner_id);
} }
/* add or copy texture */ /* add or copy texture */

View File

@ -1112,7 +1112,7 @@ static int brush_asset_save_as_exec(bContext *C, wmOperator *op)
library->catalog_service->write_to_disk(filepath); library->catalog_service->write_to_disk(filepath);
/* Save to asset library. */ /* Save to asset library. */
Main *asset_main = BKE_asset_weak_reference_main(bmain, &brush->id); Main *asset_main = BKE_main_from_id(bmain, &brush->id);
std::string final_full_asset_filepath; std::string final_full_asset_filepath;
const bool sucess = brush_asset_write_in_library(asset_main, const bool sucess = brush_asset_write_in_library(asset_main,
@ -1254,7 +1254,7 @@ static int brush_asset_delete_exec(bContext *C, wmOperator *op)
Paint *paint = BKE_paint_get_active_from_context(C); Paint *paint = BKE_paint_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint); Brush *brush = BKE_paint_brush(paint);
Main *bmain = CTX_data_main(C); Main *bmain = CTX_data_main(C);
Main *asset_main = BKE_asset_weak_reference_main(bmain, &brush->id); Main *asset_main = BKE_main_from_id(bmain, &brush->id);
bUserAssetLibrary *library = BKE_preferences_asset_library_find_by_name( bUserAssetLibrary *library = BKE_preferences_asset_library_find_by_name(
&U, paint->brush_asset_reference->asset_library_identifier); &U, paint->brush_asset_reference->asset_library_identifier);
@ -1339,7 +1339,7 @@ static int brush_asset_update_exec(bContext *C, wmOperator *op)
BLI_assert(BKE_paint_brush_is_valid_asset(brush)); BLI_assert(BKE_paint_brush_is_valid_asset(brush));
Main *asset_main = BKE_asset_weak_reference_main(bmain, &brush->id); Main *asset_main = BKE_main_from_id(bmain, &brush->id);
std::string final_full_asset_filepath; std::string final_full_asset_filepath;
brush_asset_write_in_library(asset_main, brush_asset_write_in_library(asset_main,
brush, brush,
@ -1380,7 +1380,7 @@ static int brush_asset_revert_exec(bContext *C, wmOperator * /*op*/)
Main *bmain = CTX_data_main(C); Main *bmain = CTX_data_main(C);
Paint *paint = BKE_paint_get_active_from_context(C); Paint *paint = BKE_paint_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint); Brush *brush = BKE_paint_brush(paint);
Main *asset_main = BKE_asset_weak_reference_main(bmain, &brush->id); Main *asset_main = BKE_main_from_id(bmain, &brush->id);
// TODO: delete and reload dependencies too? // TODO: delete and reload dependencies too?
// TODO: hack to make remapping work, should not be needed // TODO: hack to make remapping work, should not be needed

View File

@ -2547,7 +2547,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
sima = CTX_wm_space_image(C); sima = CTX_wm_space_image(C);
id_main = CTX_data_main(C); id_main = CTX_data_main(C);
if (data->pprop.ptr.owner_id) { if (data->pprop.ptr.owner_id) {
id_main = BKE_asset_weak_reference_main(id_main, data->pprop.ptr.owner_id); id_main = BKE_main_from_id(id_main, data->pprop.ptr.owner_id);
} }
prop = RNA_struct_find_property(op->ptr, "name"); prop = RNA_struct_find_property(op->ptr, "name");

View File

@ -286,7 +286,7 @@ int rna_ID_name_length(PointerRNA *ptr)
void rna_ID_name_set(PointerRNA *ptr, const char *value) void rna_ID_name_set(PointerRNA *ptr, const char *value)
{ {
ID *id = (ID *)ptr->data; ID *id = (ID *)ptr->data;
Main *id_main = BKE_asset_weak_reference_main(G_MAIN, id); Main *id_main = BKE_main_from_id(G_MAIN, id);
BKE_main_namemap_remove_name(id_main, id, id->name + 2); BKE_main_namemap_remove_name(id_main, id, id->name + 2);
BLI_strncpy_utf8(id->name + 2, value, sizeof(id->name) - 2); BLI_strncpy_utf8(id->name + 2, value, sizeof(id->name) - 2);
/* TODO: add BKE_id_is_in_editable_main? */ /* TODO: add BKE_id_is_in_editable_main? */
@ -1158,7 +1158,7 @@ int rna_IDMaterials_assign_int(PointerRNA *ptr, int key, const PointerRNA *assig
short *totcol = BKE_id_material_len_p(id); short *totcol = BKE_id_material_len_p(id);
Material *mat_id = (Material *)assign_ptr->owner_id; Material *mat_id = (Material *)assign_ptr->owner_id;
if (totcol && (key >= 0 && key < *totcol)) { if (totcol && (key >= 0 && key < *totcol)) {
Main *id_main = BKE_asset_weak_reference_main(G_MAIN, id); Main *id_main = BKE_main_from_id(G_MAIN, id);
/* TODO: BKE_id_is_in_editable_main? */ /* TODO: BKE_id_is_in_editable_main? */
BLI_assert(BKE_id_is_in_global_main(id)); BLI_assert(BKE_id_is_in_global_main(id));
BLI_assert(BKE_id_is_in_global_main(&mat_id->id)); BLI_assert(BKE_id_is_in_global_main(&mat_id->id));
@ -1218,7 +1218,7 @@ static void rna_IDMaterials_clear_id(ID *id, Main *bmain)
static void rna_Library_filepath_set(PointerRNA *ptr, const char *value) static void rna_Library_filepath_set(PointerRNA *ptr, const char *value)
{ {
Library *lib = (Library *)ptr->data; Library *lib = (Library *)ptr->data;
Main *id_main = BKE_asset_weak_reference_main(G_MAIN, &lib->id); Main *id_main = BKE_main_from_id(G_MAIN, &lib->id);
/* TODO: BKE_id_is_in_editable_main? */ /* TODO: BKE_id_is_in_editable_main? */
BLI_assert(BKE_id_is_in_global_main(&lib->id)); BLI_assert(BKE_id_is_in_global_main(&lib->id));
BKE_library_filepath_set(id_main, lib, value); BKE_library_filepath_set(id_main, lib, value);

View File

@ -127,7 +127,7 @@ static void rna_Main_ID_remove(Main *bmain,
return; return;
} }
/* TODO: also check reverse case somehow? */ /* TODO: also check reverse case somehow? */
if (bmain != BKE_asset_weak_reference_main(bmain, id)) { if (bmain != BKE_main_from_id(bmain, id)) {
BKE_reportf(reports, BKE_reportf(reports,
RPT_ERROR, RPT_ERROR,
"%s '%s' is part of a difference main database and should be removed from there", "%s '%s' is part of a difference main database and should be removed from there",