WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 370 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.
3 changed files with 35 additions and 66 deletions
Showing only changes of commit 3a7ebb7dc7 - Show all commits

View File

@ -201,7 +201,7 @@ PaintMode BKE_paintmode_get_from_tool(const bToolRef *tref);
Brush *BKE_paint_brush(Paint *paint); Brush *BKE_paint_brush(Paint *paint);
const Brush *BKE_paint_brush_for_read(const Paint *paint); const Brush *BKE_paint_brush_for_read(const Paint *paint);
void BKE_paint_brush_set(Paint *paint, Brush *brush); bool BKE_paint_brush_set(Paint *paint, Brush *brush);
bool BKE_paint_brush_set_default(Main *bmain, Paint *paint); bool BKE_paint_brush_set_default(Main *bmain, Paint *paint);
bool BKE_paint_brush_set_essentials(Main *bmain, Paint *paint, const char *name); bool BKE_paint_brush_set_essentials(Main *bmain, Paint *paint, const char *name);
@ -209,13 +209,6 @@ void BKE_paint_brush_set_default_references(ToolSettings *ts);
void BKE_paint_brush_validate(Main *bmain, Paint *paint); void BKE_paint_brush_validate(Main *bmain, Paint *paint);
/**
* Check if the given brush is a valid Brush Asset.
*
* A valid brush Asset is either an actual asset, or a local liboverride of a linked brush asset.
*/
bool BKE_paint_brush_is_valid_asset(const Brush *brush);
/** /**
* Set the active brush of given paint struct, and store the weak asset reference to it. * Set the active brush of given paint struct, and store the weak asset reference to it.
* \note Takes ownership of the given `weak_asset_reference`. * \note Takes ownership of the given `weak_asset_reference`.
@ -224,12 +217,6 @@ bool BKE_paint_brush_asset_set(Paint *paint,
Brush *brush, Brush *brush,
const AssetWeakReference &weak_asset_reference); const AssetWeakReference &weak_asset_reference);
/**
* Get the active brush of given paint struct, together with its weak asset reference.
* \note Returns unset optional if the active brush is not a valid Brush Asset data..
*/
std::optional<AssetWeakReference *> BKE_paint_brush_asset_get(Paint *paint, Brush **r_brush);
/* Paint palette. */ /* Paint palette. */
Palette *BKE_paint_palette(Paint *paint); Palette *BKE_paint_palette(Paint *paint);

View File

@ -636,26 +636,27 @@ static bool paint_brush_set_from_asset_reference(Main *bmain, Paint *paint)
return true; return true;
} }
Brush *BKE_paint_brush(Paint *p) Brush *BKE_paint_brush(Paint *paint)
{ {
return (Brush *)BKE_paint_brush_for_read((const Paint *)p); return (Brush *)BKE_paint_brush_for_read((const Paint *)paint);
} }
const Brush *BKE_paint_brush_for_read(const Paint *p) const Brush *BKE_paint_brush_for_read(const Paint *paint)
{ {
return p ? p->brush : nullptr; return paint ? paint->brush : nullptr;
} }
void BKE_paint_brush_set(Paint *p, Brush *br) bool BKE_paint_brush_set(Paint *paint, Brush *brush)
{ {
if (p) { if (paint == nullptr || paint->brush == brush) {
p->brush = br; return false;
}
if (brush && (paint->runtime.ob_mode & brush->ob_mode) == 0) {
return false;
} }
}
bool BKE_paint_brush_is_valid_asset(const Brush *brush) paint->brush = brush;
{ return true;
return brush && ID_IS_ASSET(&brush->id);
} }
static void paint_brush_asset_update(Paint &paint, static void paint_brush_asset_update(Paint &paint,
@ -688,21 +689,6 @@ bool BKE_paint_brush_asset_set(Paint *paint,
return true; return true;
} }
std::optional<AssetWeakReference *> BKE_paint_brush_asset_get(Paint *paint, Brush **r_brush)
{
Brush *brush = *r_brush = BKE_paint_brush(paint);
if (!BKE_paint_brush_is_valid_asset(brush)) {
return {};
}
if (paint->brush_asset_reference) {
return paint->brush_asset_reference;
}
return {};
}
static void paint_brush_set_essentials_reference(Paint *paint, const char *name) static void paint_brush_set_essentials_reference(Paint *paint, const char *name)
{ {
/* Set brush asset reference to a named brush in the essentials asset library. */ /* Set brush asset reference to a named brush in the essentials asset library. */

View File

@ -1055,11 +1055,11 @@ static int brush_asset_save_as_exec(bContext *C, wmOperator *op)
} }
/* Turn brush into asset if it isn't yet. */ /* Turn brush into asset if it isn't yet. */
if (!BKE_paint_brush_is_valid_asset(brush)) { if (!ID_IS_ASSET(brush)) {
asset::mark_id(&brush->id); asset::mark_id(&brush->id);
asset::generate_preview(C, &brush->id); asset::generate_preview(C, &brush->id);
} }
BLI_assert(BKE_paint_brush_is_valid_asset(brush)); BLI_assert(ID_IS_ASSET(brush));
asset_system::AssetLibrary *library = AS_asset_library_load( asset_system::AssetLibrary *library = AS_asset_library_load(
CTX_data_main(C), user_library_to_library_ref(*user_library)); CTX_data_main(C), user_library_to_library_ref(*user_library));
@ -1082,16 +1082,16 @@ static int brush_asset_save_as_exec(bContext *C, wmOperator *op)
Main *asset_main = BKE_main_from_id(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 success = brush_asset_write_in_library(asset_main,
brush, brush,
name, name,
filepath, filepath,
catalog_id, catalog_id,
catalog_simple_name, catalog_simple_name,
final_full_asset_filepath, final_full_asset_filepath,
op->reports); op->reports);
if (!sucess) { if (!success) {
BKE_report(op->reports, RPT_ERROR, "Failed to write to asset library"); BKE_report(op->reports, RPT_ERROR, "Failed to write to asset library");
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
} }
@ -1099,7 +1099,6 @@ static int brush_asset_save_as_exec(bContext *C, wmOperator *op)
AssetWeakReference new_brush_weak_ref = brush_asset_create_weakref_hack( AssetWeakReference new_brush_weak_ref = brush_asset_create_weakref_hack(
user_library, final_full_asset_filepath); user_library, final_full_asset_filepath);
/* TODO: maybe not needed, even less so if there is more visual confirmation of change. */
BKE_reportf(op->reports, RPT_INFO, "Saved \"%s\"", filepath.c_str()); BKE_reportf(op->reports, RPT_INFO, "Saved \"%s\"", filepath.c_str());
brush = reinterpret_cast<Brush *>( brush = reinterpret_cast<Brush *>(
@ -1213,7 +1212,7 @@ static bool brush_asset_delete_poll(bContext *C)
} }
/* Asset brush, check if belongs to an editable blend file. */ /* Asset brush, check if belongs to an editable blend file. */
if (paint->brush_asset_reference && BKE_paint_brush_is_valid_asset(brush)) { if (paint->brush_asset_reference && ID_IS_ASSET(brush)) {
if (!asset_is_editable(*paint->brush_asset_reference)) { if (!asset_is_editable(*paint->brush_asset_reference)) {
CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable"); CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable");
return false; return false;
@ -1236,7 +1235,7 @@ static int brush_asset_delete_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
} }
if (paint->brush_asset_reference && BKE_paint_brush_is_valid_asset(brush)) { if (paint->brush_asset_reference && ID_IS_ASSET(brush)) {
/* Delete from asset library on disk. */ /* Delete from asset library on disk. */
char path_buffer[FILE_MAX_LIBEXTRA]; char path_buffer[FILE_MAX_LIBEXTRA];
char *filepath; char *filepath;
@ -1284,7 +1283,11 @@ static bool brush_asset_update_poll(bContext *C)
return false; return false;
} }
if (!(paint->brush_asset_reference && BKE_paint_brush_is_valid_asset(brush))) { if ((brush->id.tag & LIB_TAG_ASSET_MAIN) == 0) {
return false;
}
if (!(paint->brush_asset_reference && ID_IS_ASSET(brush))) {
return false; return false;
} }
@ -1300,12 +1303,8 @@ static int brush_asset_update_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 = nullptr; Brush *brush = BKE_paint_brush(paint);
const AssetWeakReference *asset_weak_ref = const AssetWeakReference *asset_weak_ref = paint->brush_asset_reference;
BKE_paint_brush_asset_get(paint, &brush).value_or(nullptr);
if (!asset_weak_ref) {
return OPERATOR_CANCELLED;
}
const bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_by_name( const bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_by_name(
&U, asset_weak_ref->asset_library_identifier); &U, asset_weak_ref->asset_library_identifier);
@ -1313,15 +1312,12 @@ static int brush_asset_update_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
} }
// TODO: maybe can check directly in poll
BLI_assert((brush->id.tag & LIB_TAG_ASSET_MAIN) != 0);
char path_buffer[FILE_MAX_LIBEXTRA]; char path_buffer[FILE_MAX_LIBEXTRA];
char *filepath; char *filepath;
AS_asset_full_path_explode_from_weak_ref( AS_asset_full_path_explode_from_weak_ref(
asset_weak_ref, path_buffer, &filepath, nullptr, nullptr); asset_weak_ref, path_buffer, &filepath, nullptr, nullptr);
BLI_assert(BKE_paint_brush_is_valid_asset(brush)); BLI_assert(ID_IS_ASSET(brush));
Main *asset_main = BKE_main_from_id(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;
@ -1360,7 +1356,7 @@ static bool brush_asset_revert_poll(bContext *C)
return false; return false;
} }
return paint->brush_asset_reference && BKE_paint_brush_is_valid_asset(brush); return paint->brush_asset_reference && ID_IS_ASSET(brush);
} }
static int brush_asset_revert_exec(bContext *C, wmOperator * /*op*/) static int brush_asset_revert_exec(bContext *C, wmOperator * /*op*/)