WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 358 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.
4 changed files with 75 additions and 72 deletions
Showing only changes of commit a800bdc473 - Show all commits

View File

@ -26,6 +26,8 @@
#include <optional>
#include <string>
#include "BLI_string_ref.hh"
#include "AS_asset_catalog.hh"
#include "DNA_ID_enums.h"
@ -44,24 +46,24 @@ ID *asset_edit_id_from_weak_reference(Main &global_main,
const AssetWeakReference &weak_ref);
/** Get main database that a given asset datablock corresponds to. */
Main *asset_edit_main(const ID *id);
Main *asset_edit_main(const ID &id);
/** Asset editing operations. */
bool asset_edit_id_is_editable(const ID *id);
bool asset_edit_id_is_editable(const ID &id);
std::optional<std::string> asset_edit_id_save_as(
Main &global_main,
const ID *id,
const char *name,
const ID &id,
StringRef name,
std::optional<blender::asset_system::CatalogID> catalog_id,
std::optional<std::string> catalog_simple_name,
const bUserAssetLibrary *user_library,
ReportList *reports);
const bUserAssetLibrary &user_library,
ReportList &reports);
bool asset_edit_id_save(Main &global_main, const ID *id, ReportList *reports);
bool asset_edit_id_revert(Main &global_main, const ID *id, ReportList *reports);
bool asset_edit_id_delete(Main &global_main, const ID *id, ReportList *reports);
bool asset_edit_id_save(Main &global_main, const ID &id, ReportList &reports);
bool asset_edit_id_revert(Main &global_main, const ID &id, ReportList &reports);
bool asset_edit_id_delete(Main &global_main, const ID &id, ReportList &reports);
/** Clean up on exit. */
void asset_edit_main_free_all();

View File

@ -155,21 +155,23 @@ static std::string asset_root_path_for_save(const bUserAssetLibrary &user_librar
return std::string(libpath) + SEP + "Saved" + SEP + name;
}
static std::string asset_blendfile_path_for_save(ReportList *reports,
const bUserAssetLibrary &user_library,
const StringRefNull base_name,
const ID_Type id_type)
static std::string asset_blendfile_path_for_save(const bUserAssetLibrary &user_library,
const StringRef base_name,
const ID_Type id_type,
ReportList &reports)
{
std::string root_path = asset_root_path_for_save(user_library, id_type);
BLI_assert(!root_path.empty());
if (!BLI_dir_create_recursive(root_path.c_str())) {
BKE_report(reports, RPT_ERROR, "Failed to create asset library directory to save brush");
BKE_report(&reports, RPT_ERROR, "Failed to create asset library directory to save brush");
return "";
}
char base_name_filesafe[FILE_MAXFILE];
BLI_strncpy(base_name_filesafe, base_name.c_str(), sizeof(base_name_filesafe));
BLI_strncpy(base_name_filesafe,
base_name.data(),
std::min(sizeof(base_name_filesafe), size_t(base_name.size())));
BLI_path_make_safe_filename(base_name_filesafe);
const std::string filepath = root_path + SEP + base_name_filesafe + BLENDER_ASSET_FILE_SUFFIX;
@ -189,13 +191,13 @@ static std::string asset_blendfile_path_for_save(ReportList *reports,
}
static bool asset_write_in_library(Main *bmain,
const ID *id_const,
const char *name,
const ID &id_const,
const StringRef name,
const StringRefNull filepath,
const std::optional<asset_system::CatalogID> catalog,
const std::optional<StringRefNull> catalog_simple_name,
std::string &final_full_file_path,
ReportList *reports)
ReportList &reports)
{
/* XXX
* FIXME
@ -216,41 +218,41 @@ static bool asset_write_in_library(Main *bmain,
* - `BKE_blendfile_write_partial_end` frees the temp Main.
*/
ID *id = const_cast<ID *>(id_const);
ID &id = const_cast<ID &>(id_const);
const short prev_flag = id->flag;
const int prev_tag = id->tag;
const int prev_us = id->us;
const std::string prev_name = id->name + 2;
IDOverrideLibrary *prev_liboverride = id->override_library;
AssetMetaData *asset_data = id->asset_data;
const short prev_flag = id.flag;
const int prev_tag = id.tag;
const int prev_us = id.us;
const std::string prev_name = id.name + 2;
IDOverrideLibrary *prev_liboverride = id.override_library;
AssetMetaData *asset_data = id.asset_data;
const int write_flags = 0; /* Could use #G_FILE_COMPRESS ? */
const eBLO_WritePathRemap remap_mode = BLO_WRITE_PATH_REMAP_RELATIVE;
BKE_blendfile_write_partial_begin(bmain);
id->flag |= LIB_FAKEUSER;
id->tag &= ~LIB_TAG_RUNTIME;
id->us = 1;
BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2);
if (!ID_IS_ASSET(id)) {
id->asset_data = id->override_library->reference->asset_data;
id.flag |= LIB_FAKEUSER;
id.tag &= ~LIB_TAG_RUNTIME;
id.us = 1;
BLI_strncpy(id.name + 2, name.data(), std::min(sizeof(id.name) - 2, size_t(name.size())));
if (!ID_IS_ASSET(&id)) {
id.asset_data = id.override_library->reference->asset_data;
}
id->override_library = nullptr;
id.override_library = nullptr;
if (catalog) {
id->asset_data->catalog_id = *catalog;
id.asset_data->catalog_id = *catalog;
}
if (catalog_simple_name) {
STRNCPY(id->asset_data->catalog_simple_name, catalog_simple_name->c_str());
STRNCPY(id.asset_data->catalog_simple_name, catalog_simple_name->c_str());
}
BKE_blendfile_write_partial_tag_ID(id, true);
BKE_blendfile_write_partial_tag_ID(&id, true);
/* TODO: check overwriting existing file. */
/* TODO: ensure filepath contains only valid characters for file system. */
const bool sucess = BKE_blendfile_write_partial(
bmain, filepath.c_str(), write_flags, remap_mode, reports);
bmain, filepath.c_str(), write_flags, remap_mode, &reports);
if (sucess) {
final_full_file_path = std::string(filepath) + SEP + "Brush" + SEP + name;
@ -258,13 +260,13 @@ static bool asset_write_in_library(Main *bmain,
BKE_blendfile_write_partial_end(bmain);
BKE_blendfile_write_partial_tag_ID(id, false);
id->flag = prev_flag;
id->tag = prev_tag;
id->us = prev_us;
BLI_strncpy(id->name + 2, prev_name.c_str(), sizeof(id->name) - 2);
id->override_library = prev_liboverride;
id->asset_data = asset_data;
BKE_blendfile_write_partial_tag_ID(&id, false);
id.flag = prev_flag;
id.tag = prev_tag;
id.us = prev_us;
BLI_strncpy(id.name + 2, prev_name.c_str(), sizeof(id.name) - 2);
id.override_library = prev_liboverride;
id.asset_data = asset_data;
return sucess;
}
@ -338,15 +340,15 @@ static Vector<AssetEditBlend> &asset_edit_blend_get_all()
return mains;
}
static AssetEditBlend *asset_edit_blend_from_id(const ID *id)
static AssetEditBlend *asset_edit_blend_from_id(const ID &id)
{
BLI_assert(id->tag & LIB_TAG_ASSET_MAIN);
BLI_assert(id.tag & LIB_TAG_ASSET_MAIN);
for (AssetEditBlend &asset_blend : asset_edit_blend_get_all()) {
/* TODO: Look into make this whole thing more efficient. */
ListBase *lb = which_libbase(asset_blend.main, GS(id->name));
ListBase *lb = which_libbase(asset_blend.main, GS(id.name));
LISTBASE_FOREACH (ID *, other_id, lb) {
if (id == other_id) {
if (&id == other_id) {
return &asset_blend;
}
}
@ -356,7 +358,7 @@ static AssetEditBlend *asset_edit_blend_from_id(const ID *id)
return nullptr;
}
Main *asset_edit_main(const ID *id)
Main *asset_edit_main(const ID &id)
{
const AssetEditBlend *asset_blend = asset_edit_blend_from_id(id);
return (asset_blend) ? asset_blend->main : nullptr;
@ -375,18 +377,18 @@ static AssetEditBlend &asset_edit_blend_file_ensure(const StringRef filepath)
}
std::optional<std::string> asset_edit_id_save_as(Main &global_main,
const ID *id,
const char *name,
const ID &id,
const StringRef name,
std::optional<asset_system::CatalogID> catalog_id,
std::optional<std::string> catalog_simple_name,
const bUserAssetLibrary *user_library,
ReportList *reports)
const bUserAssetLibrary &user_library,
ReportList &reports)
{
const std::string filepath = asset_blendfile_path_for_save(
reports, *user_library, name, GS(id->name));
user_library, name, GS(id.name), reports);
/* Save to asset library. */
Main *asset_main = BKE_main_from_id(&global_main, id);
Main *asset_main = BKE_main_from_id(&global_main, &id);
std::string final_full_asset_filepath;
const bool success = asset_write_in_library(asset_main,
@ -397,18 +399,17 @@ std::optional<std::string> asset_edit_id_save_as(Main &global_main,
catalog_simple_name,
final_full_asset_filepath,
reports);
if (!success) {
BKE_report(reports, RPT_ERROR, "Failed to write to asset library");
BKE_report(&reports, RPT_ERROR, "Failed to write to asset library");
return std::nullopt;
}
BKE_reportf(reports, RPT_INFO, "Saved \"%s\"", filepath.c_str());
BKE_reportf(&reports, RPT_INFO, "Saved \"%s\"", filepath.c_str());
return final_full_asset_filepath;
}
bool asset_edit_id_save(Main & /*global_main*/, const ID *id, ReportList *reports)
bool asset_edit_id_save(Main & /*global_main*/, const ID &id, ReportList &reports)
{
AssetEditBlend *asset_blend = asset_edit_blend_from_id(id);
if (asset_blend == nullptr) {
@ -418,7 +419,7 @@ bool asset_edit_id_save(Main & /*global_main*/, const ID *id, ReportList *report
std::string final_full_asset_filepath;
const bool success = asset_write_in_library(asset_blend->main,
id,
id->name + 2,
id.name + 2,
asset_blend->filepath.c_str(),
std::nullopt,
std::nullopt,
@ -426,14 +427,14 @@ bool asset_edit_id_save(Main & /*global_main*/, const ID *id, ReportList *report
reports);
if (!success) {
BKE_report(reports, RPT_ERROR, "Failed to write to asset library");
BKE_report(&reports, RPT_ERROR, "Failed to write to asset library");
return false;
}
return true;
}
bool asset_edit_id_revert(Main &global_main, const ID *id, ReportList * /*reports*/)
bool asset_edit_id_revert(Main &global_main, const ID &id, ReportList & /*reports*/)
{
AssetEditBlend *asset_blend = asset_edit_blend_from_id(id);
if (asset_blend == nullptr) {
@ -447,7 +448,7 @@ bool asset_edit_id_revert(Main &global_main, const ID *id, ReportList * /*report
return true;
}
bool asset_edit_id_delete(Main &global_main, const ID *id, ReportList *reports)
bool asset_edit_id_delete(Main &global_main, const ID &id, ReportList &reports)
{
AssetEditBlend *asset_blend = asset_edit_blend_from_id(id);
if (asset_blend == nullptr) {
@ -455,7 +456,7 @@ bool asset_edit_id_delete(Main &global_main, const ID *id, ReportList *reports)
}
if (BLI_delete(asset_blend->filepath.c_str(), false, false) != 0) {
BKE_report(reports, RPT_ERROR, "Failed to delete asset library file");
BKE_report(&reports, RPT_ERROR, "Failed to delete asset library file");
return false;
}
@ -500,9 +501,9 @@ ID *asset_edit_id_from_weak_reference(Main &global_main,
return asset_blend.ensure_id(id_type, asset_name);
}
bool asset_edit_id_is_editable(const ID *id)
bool asset_edit_id_is_editable(const ID &id)
{
if (!(id->tag & LIB_TAG_ASSET_MAIN)) {
if (!(id.tag & LIB_TAG_ASSET_MAIN)) {
return false;
}

View File

@ -972,7 +972,7 @@ Main *BKE_main_from_id(Main *global_main, const ID *id, const bool verify)
return nullptr;
}
if (id->tag & LIB_TAG_ASSET_MAIN) {
return blender::bke::asset_edit_main(id);
return blender::bke::asset_edit_main(*id);
}
if (verify) {

View File

@ -916,7 +916,7 @@ static int brush_asset_save_as_exec(bContext *C, wmOperator *op)
}
const std::optional<std::string> final_full_asset_filepath = bke::asset_edit_id_save_as(
*bmain, &brush->id, name, catalog_id, catalog_simple_name, user_library, op->reports);
*bmain, brush->id, name, catalog_id, catalog_simple_name, *user_library, *op->reports);
if (!final_full_asset_filepath) {
return OPERATOR_CANCELLED;
@ -1100,7 +1100,7 @@ static bool brush_asset_delete_poll(bContext *C)
/* Asset brush, check if belongs to an editable blend file. */
if (ID_IS_ASSET(brush)) {
if (!bke::asset_edit_id_is_editable(&brush->id)) {
if (!bke::asset_edit_id_is_editable(brush->id)) {
CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable");
return false;
}
@ -1121,7 +1121,7 @@ static int brush_asset_delete_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
bke::asset_edit_id_delete(*bmain, &brush->id, op->reports);
bke::asset_edit_id_delete(*bmain, brush->id, *op->reports);
refresh_asset_library(C, *library);
@ -1172,7 +1172,7 @@ static bool brush_asset_update_poll(bContext *C)
return false;
}
if (!bke::asset_edit_id_is_editable(&brush->id)) {
if (!bke::asset_edit_id_is_editable(brush->id)) {
CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable");
return false;
}
@ -1195,7 +1195,7 @@ static int brush_asset_update_exec(bContext *C, wmOperator *op)
BLI_assert(ID_IS_ASSET(brush));
bke::asset_edit_id_save(*bmain, &brush->id, op->reports);
bke::asset_edit_id_save(*bmain, brush->id, *op->reports);
refresh_asset_library(C, *user_library);
WM_main_add_notifier(NC_ASSET | ND_ASSET_LIST | NA_EDITED, nullptr);
@ -1231,7 +1231,7 @@ static int brush_asset_revert_exec(bContext *C, wmOperator *op)
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint);
bke::asset_edit_id_revert(*bmain, &brush->id, op->reports);
bke::asset_edit_id_revert(*bmain, brush->id, *op->reports);
WM_main_add_notifier(NC_BRUSH | NA_EDITED, nullptr);
WM_main_add_notifier(NC_TEXTURE | ND_NODES, nullptr);