From 1fbb1d8cf6ea9badd3361e4c533625f569d14734 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Nov 2022 16:59:16 +0100 Subject: Fix T102214: inconsistenty between bake and render with invalid material index When the materal slot index on mesh faces exceeds the number of slots, rendering would use the last material slot while other operations like baking would fall back to the default material. Now consistently use the last material slot in such cases, since preserving backwards compatibility for rendering seems most important. And if there is one material slot, it's more useful to use that one rather than falling back to the default material. --- source/blender/blenkernel/intern/material.c | 47 ++++++++++++----------------- source/blender/render/intern/bake.c | 6 +++- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 59530a6d6a6..796ed4f8316 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -653,38 +653,29 @@ Material **BKE_object_material_get_p(Object *ob, short act) /* if object cannot have material, (totcolp == NULL) */ totcolp = BKE_object_material_len_p(ob); - if (totcolp == NULL || ob->totcol == 0) { + if (totcolp == NULL || *totcolp == 0) { return NULL; } - /* return NULL for invalid 'act', can happen for mesh face indices */ - if (act > ob->totcol) { - return NULL; - } - if (act <= 0) { - if (act < 0) { - CLOG_ERROR(&LOG, "Negative material index!"); - } - return NULL; - } + /* Clamp to number of slots if index is out of range, same convention as used for rendering. */ + const int slot_index = clamp_i(act - 1, 0, *totcolp - 1); - if (ob->matbits && ob->matbits[act - 1]) { /* in object */ - ma_p = &ob->mat[act - 1]; + /* Fix inconsistency which may happen when library linked data reduces the number of + * slots but object was not updated. Ideally should be fixed elsewhere. */ + if (*totcolp < ob->totcol) { + ob->totcol = *totcolp; } - else { /* in data */ - - /* check for inconsistency */ - if (*totcolp < ob->totcol) { - ob->totcol = *totcolp; - } - if (act > ob->totcol) { - act = ob->totcol; - } + if (slot_index < ob->totcol && ob->matbits && ob->matbits[slot_index]) { + /* Use object material slot. */ + ma_p = &ob->mat[slot_index]; + } + else { + /* Use data material slot. */ matarar = BKE_object_material_array_p(ob); if (matarar && *matarar) { - ma_p = &(*matarar)[act - 1]; + ma_p = &(*matarar)[slot_index]; } else { ma_p = NULL; @@ -717,17 +708,17 @@ static ID *get_evaluated_object_data_with_materials(Object *ob) Material *BKE_object_material_get_eval(Object *ob, short act) { BLI_assert(DEG_is_evaluated_object(ob)); - const int slot_index = act - 1; - if (slot_index < 0) { - return NULL; - } ID *data = get_evaluated_object_data_with_materials(ob); const short *tot_slots_data_ptr = BKE_id_material_len_p(data); const int tot_slots_data = tot_slots_data_ptr ? *tot_slots_data_ptr : 0; - if (slot_index >= tot_slots_data) { + + if (tot_slots_data == 0) { return NULL; } + + /* Clamp to number of slots if index is out of range, same convention as used for rendering. */ + const int slot_index = clamp_i(act - 1, 0, tot_slots_data - 1); const int tot_slots_object = ob->totcol; Material ***materials_data_ptr = BKE_id_material_array_p(data); diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c index 9b56e18bb26..d9f7f9fa0af 100644 --- a/source/blender/render/intern/bake.c +++ b/source/blender/render/intern/bake.c @@ -747,6 +747,7 @@ void RE_bake_pixels_populate(Mesh *me, BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); const int *material_indices = BKE_mesh_material_indices(me); + const int materials_num = targets->materials_num; for (int i = 0; i < tottri; i++) { const MLoopTri *lt = &looptri[i]; @@ -754,7 +755,10 @@ void RE_bake_pixels_populate(Mesh *me, bd.primitive_id = i; /* Find images matching this material. */ - Image *image = targets->material_to_image[material_indices ? material_indices[lt->poly] : 0]; + const int material_index = (material_indices && materials_num) ? + clamp_i(material_indices[lt->poly], 0, materials_num - 1) : + 0; + Image *image = targets->material_to_image[material_index]; for (int image_id = 0; image_id < targets->images_num; image_id++) { BakeImage *bk_image = &targets->images[image_id]; if (bk_image->image != image) { -- cgit v1.2.3 From 1efc94bb2f7b0321935ce6564b23d5d92ee41594 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 9 Nov 2022 18:34:31 +0100 Subject: Asset System: New core type to represent assets (`AssetRepresenation`) Introduces a new `AssetRepresentation` type, as a runtime only container to hold asset information. It is supposed to become _the_ main way to represent and refer to assets in the asset system, see T87235. It can store things like the asset name, asset traits, preview and other asset metadata. Technical documentation: https://wiki.blender.org/wiki/Source/Architecture/Asset_System/Back_End#Asset_Representation. By introducing a proper asset representation type, we do an important step away from the previous, non-optimal representation of assets as files in the file browser backend, and towards the asset system as backend. It should replace the temporary & hacky `AssetHandle` design in the near future. Note that the loading of asset data still happens through the file browser backend, check the linked to Wiki page for more information on that. As a side-effect, asset metadata isn't stored in file browser file entries when browsing with link/append anymore. Don't think this was ever used, but scripts may have accessed this. Can be brought back if there's a need for it. --- source/blender/blenkernel/BKE_asset.h | 19 +++ source/blender/blenkernel/BKE_asset_library.h | 40 +----- source/blender/blenkernel/BKE_asset_library.hh | 83 +++++++++++- .../blender/blenkernel/BKE_asset_representation.hh | 66 ++++++++++ source/blender/blenkernel/CMakeLists.txt | 2 + source/blender/blenkernel/intern/asset.cc | 28 ++-- source/blender/blenkernel/intern/asset_catalog.cc | 9 +- source/blender/blenkernel/intern/asset_library.cc | 90 +++++++++++-- .../blenkernel/intern/asset_library_service.cc | 25 ++-- .../blenkernel/intern/asset_library_service.hh | 8 ++ .../intern/asset_library_service_test.cc | 22 ++++ .../blenkernel/intern/asset_representation.cc | 98 ++++++++++++++ source/blender/blenkernel/intern/context.c | 2 +- source/blender/blenkernel/intern/lib_id_delete.c | 10 +- .../blender/editors/asset/intern/asset_handle.cc | 9 +- .../editors/asset/intern/asset_temp_id_consumer.cc | 2 +- source/blender/editors/include/UI_interface.h | 1 - source/blender/editors/interface/interface_drag.cc | 5 +- .../interface/interface_template_asset_view.cc | 1 - .../editors/space_file/asset_catalog_tree_view.cc | 5 +- source/blender/editors/space_file/file_draw.c | 2 - source/blender/editors/space_file/file_indexer.cc | 3 +- source/blender/editors/space_file/file_intern.h | 18 ++- source/blender/editors/space_file/filelist.cc | 144 +++++++++++---------- source/blender/editors/space_file/space_file.c | 2 +- source/blender/makesdna/DNA_asset_types.h | 6 + source/blender/makesdna/DNA_space_types.h | 4 +- source/blender/makesrna/intern/rna_space.c | 15 ++- source/blender/windowmanager/WM_api.h | 1 - source/blender/windowmanager/intern/wm_dragdrop.cc | 10 +- 30 files changed, 556 insertions(+), 174 deletions(-) create mode 100644 source/blender/blenkernel/BKE_asset_representation.hh create mode 100644 source/blender/blenkernel/intern/asset_representation.cc diff --git a/source/blender/blenkernel/BKE_asset.h b/source/blender/blenkernel/BKE_asset.h index 81b520a1db0..bcbe19c0f3e 100644 --- a/source/blender/blenkernel/BKE_asset.h +++ b/source/blender/blenkernel/BKE_asset.h @@ -23,6 +23,9 @@ struct ID; struct IDProperty; struct PreviewImage; +/** C handle for #bke::AssetRepresentation. */ +typedef struct AssetRepresentation AssetRepresentation; + typedef void (*PreSaveFn)(void *asset_ptr, struct AssetMetaData *asset_data); typedef struct AssetTypeInfo { @@ -68,6 +71,22 @@ struct PreviewImage *BKE_asset_metadata_preview_get_from_id(const struct AssetMe void BKE_asset_metadata_write(struct BlendWriter *writer, struct AssetMetaData *asset_data); void BKE_asset_metadata_read(struct BlendDataReader *reader, struct AssetMetaData *asset_data); +const char *BKE_asset_representation_name_get(const AssetRepresentation *asset) + ATTR_WARN_UNUSED_RESULT; +AssetMetaData *BKE_asset_representation_metadata_get(const AssetRepresentation *asset) + ATTR_WARN_UNUSED_RESULT; +bool BKE_asset_representation_is_local_id(const AssetRepresentation *asset) + ATTR_WARN_UNUSED_RESULT; + #ifdef __cplusplus } #endif + +#ifdef __cplusplus + +# include + +[[nodiscard]] std::unique_ptr BKE_asset_metadata_move_to_unique_ptr( + AssetMetaData *asset_data); + +#endif diff --git a/source/blender/blenkernel/BKE_asset_library.h b/source/blender/blenkernel/BKE_asset_library.h index 824bc24203d..fc648ff6976 100644 --- a/source/blender/blenkernel/BKE_asset_library.h +++ b/source/blender/blenkernel/BKE_asset_library.h @@ -6,6 +6,7 @@ #pragma once +struct IDRemapper; struct Main; #ifdef __cplusplus @@ -24,41 +25,6 @@ typedef struct AssetLibrary AssetLibrary; */ struct AssetLibrary *BKE_asset_library_load(const char *library_path); -/** - * Try to find an appropriate location for an asset library root from a file or directory path. - * Does not check if \a input_path exists. - * - * The design is made to find an appropriate asset library path from a .blend file path, but - * technically works with any file or directory as \a input_path. - * Design is: - * * If \a input_path lies within a known asset library path (i.e. an asset library registered in - * the Preferences), return the asset library path. - * * Otherwise, if \a input_path has a parent path, return the parent path (e.g. to use the - * directory a .blend file is in as asset library root). - * * If \a input_path is empty or doesn't have a parent path (e.g. because a .blend wasn't saved - * yet), there is no suitable path. The caller has to decide how to handle this case. - * - * \param r_library_path: The returned asset library path with a trailing slash, or an empty string - * if no suitable path is found. Assumed to be a buffer of at least - * #FILE_MAXDIR bytes. - * - * \return True if the function could find a valid, that is, a non-empty path to return in \a - * r_library_path. - */ -bool BKE_asset_library_find_suitable_root_path_from_path( - const char *input_path, char r_library_path[768 /* FILE_MAXDIR */]); -/** - * Uses the current location on disk of the file represented by \a bmain as input to - * #BKE_asset_library_find_suitable_root_path_from_path(). Refer to it for a design - * description. - * - * \return True if the function could find a valid, that is, a non-empty path to return in \a - * r_library_path. If \a bmain wasn't saved into a file yet, the return value will be - * false. - */ -bool BKE_asset_library_find_suitable_root_path_from_main( - const struct Main *bmain, char r_library_path[768 /* FILE_MAXDIR */]); - /** Look up the asset's catalog and copy its simple name into #asset_data. */ void BKE_asset_library_refresh_catalog_simplename(struct AssetLibrary *asset_library, struct AssetMetaData *asset_data); @@ -66,6 +32,10 @@ void BKE_asset_library_refresh_catalog_simplename(struct AssetLibrary *asset_lib /** Return whether any loaded AssetLibrary has unsaved changes to its catalogs. */ bool BKE_asset_library_has_any_unsaved_catalogs(void); +/** An asset library can include local IDs (IDs in the current file). Their pointers need to be + * remapped on change (or assets removed as IDs gets removed). */ +void BKE_asset_library_remap_ids(struct IDRemapper *mappings); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_asset_library.hh b/source/blender/blenkernel/BKE_asset_library.hh index 2058df71f6a..b6a11a6b3f4 100644 --- a/source/blender/blenkernel/BKE_asset_library.hh +++ b/source/blender/blenkernel/BKE_asset_library.hh @@ -12,6 +12,9 @@ #include "DNA_asset_types.h" +#include "BLI_string_ref.hh" +#include "BLI_vector.hh" + #include "BKE_asset_library.h" #include "BKE_asset_catalog.hh" @@ -19,27 +22,50 @@ #include +struct AssetLibraryReference; +struct Main; + namespace blender::bke { +struct AssetRepresentation; + /** * AssetLibrary provides access to an asset library's data. - * For now this is only for catalogs, later this can be expanded to indexes/caches/more. + * + * The asset library contains catalogs and storage for asset representations. It could be extended + * to also include asset indexes and more. */ struct AssetLibrary { /* Controlled by #ED_asset_catalogs_set_save_catalogs_when_file_is_saved, * for managing the "Save Catalog Changes" in the quit-confirmation dialog box. */ static bool save_catalogs_when_file_is_saved; + /** The directory representing the root of this library. */ + std::string root_path; + std::unique_ptr catalog_service; AssetLibrary(); ~AssetLibrary(); - void load(StringRefNull library_root_directory); + void load_catalogs(StringRefNull library_root_directory); /** Load catalogs that have changed on disk. */ void refresh(); + /** + * Create a representation of an asset to be considered part of this library. Once the + * representation is not needed anymore, it must be freed using #remove_asset(), or there will be + * leaking that's only cleared when the library storage is destructed (typically on exit or + * loading a different file). + */ + AssetRepresentation &add_external_asset(StringRef name, std::unique_ptr metadata); + AssetRepresentation &add_local_id_asset(ID &id); + /** Remove an asset from the library that was added using #add_external_asset() or + * #add_local_id_asset(). + * \return True on success, false if the asset couldn't be found inside the library. */ + bool remove_asset(AssetRepresentation &asset); + /** * Update `catalog_simple_name` by looking up the asset's catalog by its ID. * @@ -53,8 +79,27 @@ struct AssetLibrary { void on_blend_save_post(Main *bmain, PointerRNA **pointers, int num_pointers); + void remap_ids(struct IDRemapper &mappings); + private: bCallbackFuncStore on_save_callback_store_{}; + + /** Storage for assets (better said their representations) that are considered to be part of this + * library. Assets are not automatically loaded into this when loading an asset library. Assets + * have to be loaded externally and added to this storage via #add_external_asset() or + * #add_local_id_asset(). So this really is arbitrary storage as far as #AssetLibrary is + * concerned (allowing the API user to manage partial library storage and partial loading, so + * only relevant parts of a library are kept in memory). + * + * For now, multiple parts of Blender just keep adding their own assets to this storage. E.g. + * multiple asset browsers might load multiple representations for the same asset into this. + * Currently there is just no way to properly identify assets, or keep track of which assets are + * already in memory and which not. Neither do we keep track of how many parts of Blender are + * using an asset or an asset library, which is needed to know when assets can be freed. + */ + Vector> asset_storage_; + + std::optional find_asset_index(const AssetRepresentation &asset); }; Vector all_valid_asset_library_refs(); @@ -64,6 +109,40 @@ Vector all_valid_asset_library_refs(); blender::bke::AssetLibrary *BKE_asset_library_load(const Main *bmain, const AssetLibraryReference &library_reference); +/** + * Try to find an appropriate location for an asset library root from a file or directory path. + * Does not check if \a input_path exists. + * + * The design is made to find an appropriate asset library path from a .blend file path, but + * technically works with any file or directory as \a input_path. + * Design is: + * * If \a input_path lies within a known asset library path (i.e. an asset library registered in + * the Preferences), return the asset library path. + * * Otherwise, if \a input_path has a parent path, return the parent path (e.g. to use the + * directory a .blend file is in as asset library root). + * * If \a input_path is empty or doesn't have a parent path (e.g. because a .blend wasn't saved + * yet), there is no suitable path. The caller has to decide how to handle this case. + * + * \param r_library_path: The returned asset library path with a trailing slash, or an empty string + * if no suitable path is found. Assumed to be a buffer of at least + * #FILE_MAXDIR bytes. + * + * \return True if the function could find a valid, that is, a non-empty path to return in \a + * r_library_path. + */ +std::string BKE_asset_library_find_suitable_root_path_from_path(blender::StringRefNull input_path); + +/** + * Uses the current location on disk of the file represented by \a bmain as input to + * #BKE_asset_library_find_suitable_root_path_from_path(). Refer to it for a design + * description. + * + * \return True if the function could find a valid, that is, a non-empty path to return in \a + * r_library_path. If \a bmain wasn't saved into a file yet, the return value will be + * false. + */ +std::string BKE_asset_library_find_suitable_root_path_from_main(const struct Main *bmain); + blender::bke::AssetCatalogService *BKE_asset_library_get_catalog_service( const ::AssetLibrary *library); blender::bke::AssetCatalogTree *BKE_asset_library_get_catalog_tree(const ::AssetLibrary *library); diff --git a/source/blender/blenkernel/BKE_asset_representation.hh b/source/blender/blenkernel/BKE_asset_representation.hh new file mode 100644 index 00000000000..0297e35c18c --- /dev/null +++ b/source/blender/blenkernel/BKE_asset_representation.hh @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup bke + */ + +#pragma once + +#include +#include + +#include "BLI_string_ref.hh" + +struct AssetMetaData; +struct ID; + +namespace blender::bke { + +/** + * \brief Abstraction to reference an asset, with necessary data for display & interaction. + * + * #AssetRepresentation is the data-structure to store information about a single asset. It doesn't + * contain the asset itself, but information like the metadata and preview, as well as methods to + * interact with them. Think of it like a view on an asset. + */ +class AssetRepresentation { + friend class AssetLibrary; + + struct ExternalAsset { + std::string name; + std::unique_ptr metadata_ = nullptr; + }; + + /** Indicate if this is a local or external asset, and as such, which of the union members below + * should be used. */ + const bool is_local_id_ = false; + + union { + ExternalAsset external_asset_; + ID *local_asset_id_ = nullptr; /* Non-owning. */ + }; + + public: + /** Constructs an asset representation for an external ID. The asset will not be editable. */ + explicit AssetRepresentation(StringRef name, std::unique_ptr metadata); + /** Constructs an asset representation for an ID stored in the current file. This makes the asset + * local and fully editable. */ + explicit AssetRepresentation(ID &id); + AssetRepresentation(AssetRepresentation &&other); + /* Non-copyable type. */ + AssetRepresentation(const AssetRepresentation &other) = delete; + ~AssetRepresentation(); + + /* Non-move-assignable type. Move construction is fine, but treat the "identity" (e.g. local vs + * external asset) of an asset representation as immutable. */ + AssetRepresentation &operator=(AssetRepresentation &&other) = delete; + /* Non-copyable type. */ + AssetRepresentation &operator=(const AssetRepresentation &other) = delete; + + StringRefNull get_name() const; + AssetMetaData &get_metadata() const; + /** Returns if this asset is stored inside this current file, and as such fully editable. */ + bool is_local_id() const; +}; + +} // namespace blender::bke diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 7d43fa7e6af..462ccc19601 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -75,6 +75,7 @@ set(SRC intern/asset_catalog_path.cc intern/asset_library.cc intern/asset_library_service.cc + intern/asset_representation.cc intern/attribute.cc intern/attribute_access.cc intern/attribute_math.cc @@ -324,6 +325,7 @@ set(SRC BKE_asset_catalog_path.hh BKE_asset_library.h BKE_asset_library.hh + BKE_asset_representation.hh BKE_attribute.h BKE_attribute.hh BKE_attribute_math.hh diff --git a/source/blender/blenkernel/intern/asset.cc b/source/blender/blenkernel/intern/asset.cc index 67802b1d6b4..7103e017847 100644 --- a/source/blender/blenkernel/intern/asset.cc +++ b/source/blender/blenkernel/intern/asset.cc @@ -27,21 +27,31 @@ using namespace blender; AssetMetaData *BKE_asset_metadata_create() { - AssetMetaData *asset_data = (AssetMetaData *)MEM_callocN(sizeof(*asset_data), __func__); - memcpy(asset_data, DNA_struct_default_get(AssetMetaData), sizeof(*asset_data)); - return asset_data; + const AssetMetaData *default_metadata = DNA_struct_default_get(AssetMetaData); + return MEM_new(__func__, *default_metadata); } void BKE_asset_metadata_free(AssetMetaData **asset_data) { - if ((*asset_data)->properties) { - IDP_FreeProperty((*asset_data)->properties); + (*asset_data)->~AssetMetaData(); + MEM_SAFE_FREE(*asset_data); +} + +AssetMetaData::~AssetMetaData() +{ + if (properties) { + IDP_FreeProperty(properties); } - MEM_SAFE_FREE((*asset_data)->author); - MEM_SAFE_FREE((*asset_data)->description); - BLI_freelistN(&(*asset_data)->tags); + MEM_SAFE_FREE(author); + MEM_SAFE_FREE(description); + BLI_freelistN(&tags); +} - MEM_SAFE_FREE(*asset_data); +std::unique_ptr BKE_asset_metadata_move_to_unique_ptr(AssetMetaData *asset_data) +{ + std::unique_ptr unique_asset_data = std::make_unique(*asset_data); + *asset_data = *DNA_struct_default_get(AssetMetaData); + return unique_asset_data; } static AssetTag *asset_metadata_tag_add(AssetMetaData *asset_data, const char *const name) diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc index 62d03b2d79b..a9fe59eba64 100644 --- a/source/blender/blenkernel/intern/asset_catalog.cc +++ b/source/blender/blenkernel/intern/asset_catalog.cc @@ -508,14 +508,13 @@ CatalogFilePath AssetCatalogService::find_suitable_cdf_path_for_writing( "catalog definition file should be put"); /* Ask the asset library API for an appropriate location. */ - char suitable_root_path[PATH_MAX]; - const bool asset_lib_root_found = BKE_asset_library_find_suitable_root_path_from_path( - blend_file_path.c_str(), suitable_root_path); - if (asset_lib_root_found) { + const std::string suitable_root_path = BKE_asset_library_find_suitable_root_path_from_path( + blend_file_path); + if (!suitable_root_path.empty()) { char asset_lib_cdf_path[PATH_MAX]; BLI_path_join(asset_lib_cdf_path, sizeof(asset_lib_cdf_path), - suitable_root_path, + suitable_root_path.c_str(), DEFAULT_CATALOG_FILENAME.c_str()); return asset_lib_cdf_path; } diff --git a/source/blender/blenkernel/intern/asset_library.cc b/source/blender/blenkernel/intern/asset_library.cc index b8420af1168..4dccee425c6 100644 --- a/source/blender/blenkernel/intern/asset_library.cc +++ b/source/blender/blenkernel/intern/asset_library.cc @@ -7,11 +7,14 @@ #include #include "BKE_asset_library.hh" +#include "BKE_asset_representation.hh" +#include "BKE_lib_remap.h" #include "BKE_main.h" #include "BKE_preferences.h" #include "BLI_fileops.h" #include "BLI_path_util.h" +#include "BLI_set.hh" #include "DNA_asset_types.h" #include "DNA_userdef_types.h" @@ -50,22 +53,22 @@ bool BKE_asset_library_has_any_unsaved_catalogs() return service->has_any_unsaved_catalogs(); } -bool BKE_asset_library_find_suitable_root_path_from_path(const char *input_path, - char *r_library_path) +std::string BKE_asset_library_find_suitable_root_path_from_path( + const blender::StringRefNull input_path) { if (bUserAssetLibrary *preferences_lib = BKE_preferences_asset_library_containing_path( - &U, input_path)) { - BLI_strncpy(r_library_path, preferences_lib->path, FILE_MAXDIR); - return true; + &U, input_path.c_str())) { + return preferences_lib->path; } - BLI_split_dir_part(input_path, r_library_path, FILE_MAXDIR); - return r_library_path[0] != '\0'; + char buffer[FILE_MAXDIR]; + BLI_split_dir_part(input_path.c_str(), buffer, FILE_MAXDIR); + return buffer; } -bool BKE_asset_library_find_suitable_root_path_from_main(const Main *bmain, char *r_library_path) +std::string BKE_asset_library_find_suitable_root_path_from_main(const Main *bmain) { - return BKE_asset_library_find_suitable_root_path_from_path(bmain->filepath, r_library_path); + return BKE_asset_library_find_suitable_root_path_from_path(bmain->filepath); } blender::bke::AssetCatalogService *BKE_asset_library_get_catalog_service( @@ -98,6 +101,13 @@ void BKE_asset_library_refresh_catalog_simplename(struct AssetLibrary *asset_lib lib->refresh_catalog_simplename(asset_data); } +void BKE_asset_library_remap_ids(IDRemapper *mappings) +{ + blender::bke::AssetLibraryService *service = blender::bke::AssetLibraryService::get(); + service->foreach_loaded_asset_library( + [mappings](blender::bke::AssetLibrary &library) { library.remap_ids(*mappings); }); +} + namespace blender::bke { AssetLibrary::AssetLibrary() : catalog_service(std::make_unique()) @@ -111,7 +121,7 @@ AssetLibrary::~AssetLibrary() } } -void AssetLibrary::load(StringRefNull library_root_directory) +void AssetLibrary::load_catalogs(StringRefNull library_root_directory) { auto catalog_service = std::make_unique(library_root_directory); catalog_service->load_from_disk(); @@ -123,6 +133,44 @@ void AssetLibrary::refresh() this->catalog_service->reload_catalogs(); } +AssetRepresentation &AssetLibrary::add_external_asset(StringRef name, + std::unique_ptr metadata) +{ + asset_storage_.append(std::make_unique(name, std::move(metadata))); + return *asset_storage_.last(); +} + +AssetRepresentation &AssetLibrary::add_local_id_asset(ID &id) +{ + asset_storage_.append(std::make_unique(id)); + return *asset_storage_.last(); +} + +std::optional AssetLibrary::find_asset_index(const AssetRepresentation &asset) +{ + int index = 0; + /* Find index of asset. */ + for (auto &asset_uptr : asset_storage_) { + if (&asset == asset_uptr.get()) { + return index; + } + index++; + } + + return {}; +} + +bool AssetLibrary::remove_asset(AssetRepresentation &asset) +{ + std::optional asset_index = find_asset_index(asset); + if (!asset_index) { + return false; + } + + asset_storage_.remove_and_reorder(*asset_index); + return true; +} + namespace { void asset_library_on_save_post(struct Main *main, struct PointerRNA **pointers, @@ -166,6 +214,28 @@ void AssetLibrary::on_blend_save_post(struct Main *main, } } +void AssetLibrary::remap_ids(IDRemapper &mappings) +{ + Set removed_id_assets; + + for (auto &asset_uptr : asset_storage_) { + if (!asset_uptr->is_local_id()) { + continue; + } + + IDRemapperApplyResult result = BKE_id_remapper_apply( + &mappings, &asset_uptr->local_asset_id_, ID_REMAP_APPLY_DEFAULT); + if (result == ID_REMAP_RESULT_SOURCE_UNASSIGNED) { + removed_id_assets.add(asset_uptr.get()); + } + } + + /* Remove the assets from storage. */ + for (AssetRepresentation *asset : removed_id_assets) { + remove_asset(*asset); + } +} + void AssetLibrary::refresh_catalog_simplename(struct AssetMetaData *asset_data) { if (BLI_uuid_is_nil(asset_data->catalog_id)) { diff --git a/source/blender/blenkernel/intern/asset_library_service.cc b/source/blender/blenkernel/intern/asset_library_service.cc index cd8de7908bf..35441b9b795 100644 --- a/source/blender/blenkernel/intern/asset_library_service.cc +++ b/source/blender/blenkernel/intern/asset_library_service.cc @@ -6,6 +6,7 @@ #include "asset_library_service.hh" +#include "BKE_asset_library.hh" #include "BKE_blender.h" #include "BKE_preferences.h" @@ -47,15 +48,10 @@ AssetLibrary *AssetLibraryService::get_asset_library( { if (library_reference.type == ASSET_LIBRARY_LOCAL) { /* For the "Current File" library we get the asset library root path based on main. */ - char root_path[FILE_MAX]; - if (bmain) { - BKE_asset_library_find_suitable_root_path_from_main(bmain, root_path); - } - else { - root_path[0] = '\0'; - } + std::string root_path = bmain ? BKE_asset_library_find_suitable_root_path_from_main(bmain) : + ""; - if (root_path[0] == '\0') { + if (root_path.empty()) { /* File wasn't saved yet. */ return get_asset_library_current_file(); } @@ -104,7 +100,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_on_disk(StringRefNull top_l AssetLibrary *lib = lib_uptr.get(); lib->on_blend_save_handler_register(); - lib->load(top_dir_trailing_slash); + lib->load_catalogs(top_dir_trailing_slash); on_disk_libraries_.add_new(top_dir_trailing_slash, std::move(lib_uptr)); CLOG_INFO(&LOG, 2, "get \"%s\" (loaded)", top_dir_trailing_slash.c_str()); @@ -180,4 +176,15 @@ bool AssetLibraryService::has_any_unsaved_catalogs() const return false; } +void AssetLibraryService::foreach_loaded_asset_library(FunctionRef fn) const +{ + if (current_file_library_) { + fn(*current_file_library_); + } + + for (const auto &asset_lib_uptr : on_disk_libraries_.values()) { + fn(*asset_lib_uptr); + } +} + } // namespace blender::bke diff --git a/source/blender/blenkernel/intern/asset_library_service.hh b/source/blender/blenkernel/intern/asset_library_service.hh index c22c6b182ce..6caaea72875 100644 --- a/source/blender/blenkernel/intern/asset_library_service.hh +++ b/source/blender/blenkernel/intern/asset_library_service.hh @@ -12,10 +12,13 @@ #include "BKE_asset_library.hh" +#include "BLI_function_ref.hh" #include "BLI_map.hh" #include +struct AssetLibraryReference; + namespace blender::bke { /** @@ -58,11 +61,16 @@ class AssetLibraryService { /** Returns whether there are any known asset libraries with unsaved catalog edits. */ bool has_any_unsaved_catalogs() const; + void foreach_loaded_asset_library(FunctionRef fn) const; + protected: static std::unique_ptr instance_; /* Mapping absolute path of the library's top-level directory to the AssetLibrary instance. */ Map on_disk_libraries_; + /** Library without a known path, i.e. the "Current File" library if the file isn't saved yet. If + * the file was saved, a valid path for the library can be determined and #on_disk_libraries_ + * above should be used. */ AssetLibraryPtr current_file_library_; /* Handlers for managing the life cycle of the AssetLibraryService instance. */ diff --git a/source/blender/blenkernel/intern/asset_library_service_test.cc b/source/blender/blenkernel/intern/asset_library_service_test.cc index 7952e7ea3b0..b68e47c9d0d 100644 --- a/source/blender/blenkernel/intern/asset_library_service_test.cc +++ b/source/blender/blenkernel/intern/asset_library_service_test.cc @@ -8,6 +8,9 @@ #include "BKE_appdir.h" #include "BKE_callbacks.h" +#include "BKE_main.h" + +#include "DNA_asset_types.h" #include "CLG_log.h" @@ -102,6 +105,25 @@ TEST_F(AssetLibraryServiceTest, library_pointers) * cannot be reliably tested by just pointer comparison, though. */ } +TEST_F(AssetLibraryServiceTest, library_from_reference) +{ + AssetLibraryService *service = AssetLibraryService::get(); + AssetLibrary *const lib = service->get_asset_library_on_disk(asset_library_root_); + AssetLibrary *const curfile_lib = service->get_asset_library_current_file(); + + AssetLibraryReference ref{}; + ref.type = ASSET_LIBRARY_LOCAL; + EXPECT_EQ(curfile_lib, service->get_asset_library(nullptr, ref)) + << "Getting the local (current file) reference without a main saved on disk should return " + "the current file library"; + + Main dummy_main{}; + BLI_strncpy(dummy_main.filepath, asset_library_root_.c_str(), sizeof(dummy_main.filepath)); + EXPECT_EQ(lib, service->get_asset_library(&dummy_main, ref)) + << "Getting the local (current file) reference with a main saved on disk should return " + "the an asset library for this directory"; +} + TEST_F(AssetLibraryServiceTest, library_path_trailing_slashes) { AssetLibraryService *service = AssetLibraryService::get(); diff --git a/source/blender/blenkernel/intern/asset_representation.cc b/source/blender/blenkernel/intern/asset_representation.cc new file mode 100644 index 00000000000..bbaa634d5ad --- /dev/null +++ b/source/blender/blenkernel/intern/asset_representation.cc @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup bke + */ + +#include + +#include "DNA_ID.h" +#include "DNA_asset_types.h" + +#include "BKE_asset.h" +#include "BKE_asset_representation.hh" + +namespace blender::bke { + +AssetRepresentation::AssetRepresentation(StringRef name, std::unique_ptr metadata) + : is_local_id_(false), external_asset_() +{ + external_asset_.name = name; + external_asset_.metadata_ = std::move(metadata); +} + +AssetRepresentation::AssetRepresentation(ID &id) : is_local_id_(true), local_asset_id_(&id) +{ + if (!id.asset_data) { + throw std::invalid_argument("Passed ID is not an asset"); + } +} + +AssetRepresentation::AssetRepresentation(AssetRepresentation &&other) + : is_local_id_(other.is_local_id_) +{ + if (is_local_id_) { + local_asset_id_ = other.local_asset_id_; + other.local_asset_id_ = nullptr; + } + else { + external_asset_ = std::move(other.external_asset_); + } +} + +AssetRepresentation::~AssetRepresentation() +{ + if (!is_local_id_) { + external_asset_.~ExternalAsset(); + } +} + +StringRefNull AssetRepresentation::get_name() const +{ + if (is_local_id_) { + return local_asset_id_->name + 2; + } + + return external_asset_.name; +} + +AssetMetaData &AssetRepresentation::get_metadata() const +{ + return is_local_id_ ? *local_asset_id_->asset_data : *external_asset_.metadata_; +} + +bool AssetRepresentation::is_local_id() const +{ + return is_local_id_; +} + +} // namespace blender::bke + +/* ---------------------------------------------------------------------- */ +/** \name C-API + * \{ */ + +using namespace blender; + +const char *BKE_asset_representation_name_get(const AssetRepresentation *asset_handle) +{ + const bke::AssetRepresentation *asset = reinterpret_cast( + asset_handle); + return asset->get_name().c_str(); +} + +AssetMetaData *BKE_asset_representation_metadata_get(const AssetRepresentation *asset_handle) +{ + const bke::AssetRepresentation *asset = reinterpret_cast( + asset_handle); + return &asset->get_metadata(); +} + +bool BKE_asset_representation_is_local_id(const AssetRepresentation *asset_handle) +{ + const bke::AssetRepresentation *asset = reinterpret_cast( + asset_handle); + return asset->is_local_id(); +} + +/** \} */ diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 1d6092849cc..0ddd53ccb99 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -1495,7 +1495,7 @@ AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid) * require returning a non-owning pointer, which we don't have in the Asset Browser (yet). */ FileDirEntry *file = (FileDirEntry *)CTX_data_pointer_get_type(C, "active_file", &RNA_FileSelectEntry).data; - if (file && file->asset_data) { + if (file && file->asset) { *r_is_valid = true; return (AssetHandle){.file_data = file}; } diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c index c7643c56212..92b34b9e1af 100644 --- a/source/blender/blenkernel/intern/lib_id_delete.c +++ b/source/blender/blenkernel/intern/lib_id_delete.c @@ -21,6 +21,7 @@ #include "BKE_anim_data.h" #include "BKE_asset.h" +#include "BKE_asset_library.h" #include "BKE_idprop.h" #include "BKE_idtype.h" #include "BKE_key.h" @@ -137,16 +138,16 @@ void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_i BKE_main_lock(bmain); } + struct IDRemapper *remapper = BKE_id_remapper_create(); + BKE_id_remapper_add(remapper, id, NULL); + if ((flag & LIB_ID_FREE_NO_UI_USER) == 0) { if (free_notifier_reference_cb) { free_notifier_reference_cb(id); } if (remap_editor_id_reference_cb) { - struct IDRemapper *remapper = BKE_id_remapper_create(); - BKE_id_remapper_add(remapper, id, NULL); remap_editor_id_reference_cb(remapper); - BKE_id_remapper_free(remapper); } } @@ -158,6 +159,9 @@ void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_i } } + BKE_asset_library_remap_ids(remapper); + BKE_id_remapper_free(remapper); + BKE_libblock_free_data(id, (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0); if ((flag & LIB_ID_FREE_NO_MAIN) == 0) { diff --git a/source/blender/editors/asset/intern/asset_handle.cc b/source/blender/editors/asset/intern/asset_handle.cc index 00fffd595c0..0b2cd352d77 100644 --- a/source/blender/editors/asset/intern/asset_handle.cc +++ b/source/blender/editors/asset/intern/asset_handle.cc @@ -8,6 +8,9 @@ #include "DNA_space_types.h" +#include "BKE_asset.h" +#include "BKE_asset_representation.hh" + #include "BLO_readfile.h" #include "ED_asset_handle.h" @@ -17,12 +20,12 @@ const char *ED_asset_handle_get_name(const AssetHandle *asset) { - return asset->file_data->name; + return BKE_asset_representation_name_get(asset->file_data->asset); } -AssetMetaData *ED_asset_handle_get_metadata(const AssetHandle *asset) +AssetMetaData *ED_asset_handle_get_metadata(const AssetHandle *asset_handle) { - return asset->file_data->asset_data; + return BKE_asset_representation_metadata_get(asset_handle->file_data->asset); } ID *ED_asset_handle_get_local_id(const AssetHandle *asset) diff --git a/source/blender/editors/asset/intern/asset_temp_id_consumer.cc b/source/blender/editors/asset/intern/asset_temp_id_consumer.cc index 376454d62b6..d1fd48d966c 100644 --- a/source/blender/editors/asset/intern/asset_temp_id_consumer.cc +++ b/source/blender/editors/asset/intern/asset_temp_id_consumer.cc @@ -72,7 +72,7 @@ AssetTempIDConsumer *ED_asset_temp_id_consumer_create(const AssetHandle *handle) if (!handle) { return nullptr; } - BLI_assert(handle->file_data->asset_data != nullptr); + BLI_assert(handle->file_data->asset != nullptr); return reinterpret_cast( MEM_new(__func__, *handle)); } diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 66b3d9fba6b..415356d1d71 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1789,7 +1789,6 @@ void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, float scale); void UI_but_drag_set_asset(uiBut *but, const struct AssetHandle *asset, const char *path, - struct AssetMetaData *metadata, int import_type, /* eFileAssetImportType */ int icon, struct ImBuf *imb, diff --git a/source/blender/editors/interface/interface_drag.cc b/source/blender/editors/interface/interface_drag.cc index 4bf2dac4151..e959986d19e 100644 --- a/source/blender/editors/interface/interface_drag.cc +++ b/source/blender/editors/interface/interface_drag.cc @@ -27,15 +27,14 @@ void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, const float scale) } void UI_but_drag_set_asset(uiBut *but, - const AssetHandle *asset, + const AssetHandle *asset_handle, const char *path, - struct AssetMetaData *metadata, int import_type, int icon, struct ImBuf *imb, float scale) { - wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, metadata, path, import_type); + wmDragAsset *asset_drag = WM_drag_create_asset_data(asset_handle, path, import_type); /* FIXME: This is temporary evil solution to get scene/view-layer/etc in the copy callback of the * #wmDropBox. diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc index 11fe653724c..9a3f7800c64 100644 --- a/source/blender/editors/interface/interface_template_asset_view.cc +++ b/source/blender/editors/interface/interface_template_asset_view.cc @@ -57,7 +57,6 @@ static void asset_view_item_but_drag_set(uiBut *but, UI_but_drag_set_asset(but, asset_handle, BLI_strdup(blend_path), - ED_asset_handle_get_metadata(asset_handle), FILE_ASSET_IMPORT_APPEND, ED_asset_handle_get_preview_icon_id(asset_handle), imbuf, diff --git a/source/blender/editors/space_file/asset_catalog_tree_view.cc b/source/blender/editors/space_file/asset_catalog_tree_view.cc index 4eb2958f5a2..fe2e46fc056 100644 --- a/source/blender/editors/space_file/asset_catalog_tree_view.cc +++ b/source/blender/editors/space_file/asset_catalog_tree_view.cc @@ -708,12 +708,11 @@ bool file_set_asset_catalog_filter_settings( void file_ensure_updated_catalog_filter_data( FileAssetCatalogFilterSettingsHandle *filter_settings_handle, - const ::AssetLibrary *asset_library) + const bke::AssetLibrary *asset_library) { AssetCatalogFilterSettings *filter_settings = reinterpret_cast( filter_settings_handle); - const AssetCatalogService *catalog_service = BKE_asset_library_get_catalog_service( - asset_library); + const AssetCatalogService *catalog_service = asset_library->catalog_service.get(); if (filter_settings->asset_catalog_visibility != FILE_SHOW_ASSETS_ALL_CATALOGS) { filter_settings->catalog_filter = std::make_unique( diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 240901318b5..ed0132c6990 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -171,7 +171,6 @@ static void file_draw_icon(const SpaceFile *sfile, UI_but_drag_set_asset(but, &(AssetHandle){.file_data = file}, BLI_strdup(blend_path), - file->asset_data, asset_params->import_type, icon, preview_image, @@ -565,7 +564,6 @@ static void file_draw_preview(const SpaceFile *sfile, UI_but_drag_set_asset(but, &(AssetHandle){.file_data = file}, BLI_strdup(blend_path), - file->asset_data, asset_params->import_type, icon, imb, diff --git a/source/blender/editors/space_file/file_indexer.cc b/source/blender/editors/space_file/file_indexer.cc index ec631eb48b3..8520ac34122 100644 --- a/source/blender/editors/space_file/file_indexer.cc +++ b/source/blender/editors/space_file/file_indexer.cc @@ -67,8 +67,9 @@ void ED_file_indexer_entries_extend_from_datablock_infos( } } -static void ED_file_indexer_entry_free(void *indexer_entry) +static void ED_file_indexer_entry_free(void *indexer_entry_ptr) { + FileIndexerEntry *indexer_entry = static_cast(indexer_entry_ptr); MEM_freeN(indexer_entry); } diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index eac72af00ab..0ca09487507 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -218,6 +218,17 @@ void file_path_to_ui_path(const char *path, char *r_pathi, int max_size); /* C-handle for #ed::asset_browser::AssetCatalogFilterSettings. */ typedef struct FileAssetCatalogFilterSettingsHandle FileAssetCatalogFilterSettingsHandle; +void file_create_asset_catalog_tree_view_in_layout(struct AssetLibrary *asset_library, + struct uiLayout *layout, + SpaceFile *space_file, + FileAssetSelectParams *params); + +#ifdef __cplusplus + +namespace blender::bke { +struct AssetLibrary; +} + FileAssetCatalogFilterSettingsHandle *file_create_asset_catalog_filter_settings(void); void file_delete_asset_catalog_filter_settings( FileAssetCatalogFilterSettingsHandle **filter_settings_handle); @@ -231,15 +242,12 @@ bool file_set_asset_catalog_filter_settings( bUUID catalog_id); void file_ensure_updated_catalog_filter_data( FileAssetCatalogFilterSettingsHandle *filter_settings_handle, - const struct AssetLibrary *asset_library); + const blender::bke::AssetLibrary *asset_library); bool file_is_asset_visible_in_catalog_filter_settings( const FileAssetCatalogFilterSettingsHandle *filter_settings_handle, const AssetMetaData *asset_data); -void file_create_asset_catalog_tree_view_in_layout(struct AssetLibrary *asset_library, - struct uiLayout *layout, - struct SpaceFile *space_file, - struct FileAssetSelectParams *params); +#endif #ifdef __cplusplus } diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index 9ca5b1da7da..c4d99d41a60 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -43,6 +43,8 @@ #include "BKE_asset.h" #include "BKE_asset_library.h" +#include "BKE_asset_library.hh" +#include "BKE_asset_representation.hh" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_icons.h" @@ -78,6 +80,8 @@ #include "file_intern.h" #include "filelist.h" +using namespace blender; + #define FILEDIR_NBR_ENTRIES_UNSET -1 /* ------------------FILELIST------------------------ */ @@ -95,7 +99,7 @@ struct FileListInternEntry { /** Optional argument for shortcuts, aliases etc. */ char *redirection_path; /** not strictly needed, but used during sorting, avoids to have to recompute it there... */ - char *name; + const char *name; bool free_name; /** @@ -112,9 +116,8 @@ struct FileListInternEntry { PreviewImage *preview_image; } local_data; - /** When the file represents an asset read from another file, it is stored here. - * Owning pointer. */ - AssetMetaData *imported_asset_data; + /* References an asset in the asset library storage. */ + bke::AssetRepresentation *asset; /* Non-owning. */ /* See #FILE_ENTRY_BLENDERLIB_NO_PREVIEW. */ bool blenderlib_has_no_preview; @@ -210,7 +213,7 @@ struct FileList { eFileSelectType type; /* The library this list was created for. Stored here so we know when to re-read. */ AssetLibraryReference *asset_library_ref; - AssetLibrary *asset_library; /* Non-owning pointer. */ + bke::AssetLibrary *asset_library; /* Non-owning. */ short flags; @@ -776,8 +779,10 @@ static bool is_filtered_id_file_type(const FileListInternEntry *file, */ static AssetMetaData *filelist_file_internal_get_asset_data(const FileListInternEntry *file) { - const ID *local_id = file->local_data.id; - return local_id ? local_id->asset_data : file->imported_asset_data; + if (!file->asset) { + return nullptr; + } + return &file->asset->get_metadata(); } static void prepare_filter_asset_library(const FileList *filelist, FileListFilter *filter) @@ -1016,7 +1021,7 @@ void filelist_setindexer(FileList *filelist, const FileIndexerType *indexer) void filelist_set_asset_catalog_filter_options( FileList *filelist, eFileSel_Params_AssetCatalogVisibility catalog_visibility, - const bUUID *catalog_id) + const ::bUUID *catalog_id) { if (!filelist->filter_data.asset_catalog_filter) { /* There's no filter data yet. */ @@ -1362,7 +1367,7 @@ static bool filelist_checkdir_main_assets(struct FileList * /*filelist*/, static void filelist_entry_clear(FileDirEntry *entry) { if (entry->name && ((entry->flags & FILE_ENTRY_NAME_FREE) != 0)) { - MEM_freeN(entry->name); + MEM_freeN((char *)entry->name); } if (entry->relpath) { MEM_freeN(entry->relpath); @@ -1399,8 +1404,13 @@ static void filelist_direntryarr_free(FileDirEntryArr *array) array->entries_filtered_num = FILEDIR_NBR_ENTRIES_UNSET; } -static void filelist_intern_entry_free(FileListInternEntry *entry) +static void filelist_intern_entry_free(FileList *filelist, FileListInternEntry *entry) { + if (entry->asset) { + BLI_assert(filelist->asset_library); + filelist->asset_library->remove_asset(*entry->asset); + } + if (entry->relpath) { MEM_freeN(entry->relpath); } @@ -1408,19 +1418,16 @@ static void filelist_intern_entry_free(FileListInternEntry *entry) MEM_freeN(entry->redirection_path); } if (entry->name && entry->free_name) { - MEM_freeN(entry->name); - } - /* If we own the asset-data (it was generated from external file data), free it. */ - if (entry->imported_asset_data) { - BKE_asset_metadata_free(&entry->imported_asset_data); + MEM_freeN((char *)entry->name); } MEM_freeN(entry); } -static void filelist_intern_free(FileListIntern *filelist_intern) +static void filelist_intern_free(FileList *filelist) { + FileListIntern *filelist_intern = &filelist->filelist_intern; LISTBASE_FOREACH_MUTABLE (FileListInternEntry *, entry, &filelist_intern->entries) { - filelist_intern_entry_free(entry); + filelist_intern_entry_free(filelist, entry); } BLI_listbase_clear(&filelist_intern->entries); @@ -1430,8 +1437,9 @@ static void filelist_intern_free(FileListIntern *filelist_intern) /** * \return the number of main files removed. */ -static int filelist_intern_free_main_files(FileListIntern *filelist_intern) +static int filelist_intern_free_main_files(FileList *filelist) { + FileListIntern *filelist_intern = &filelist->filelist_intern; int removed_counter = 0; LISTBASE_FOREACH_MUTABLE (FileListInternEntry *, entry, &filelist_intern->entries) { if (!filelist_intern_entry_is_main_file(entry)) { @@ -1439,7 +1447,7 @@ static int filelist_intern_free_main_files(FileListIntern *filelist_intern) } BLI_remlink(&filelist_intern->entries, entry); - filelist_intern_entry_free(entry); + filelist_intern_entry_free(filelist, entry); removed_counter++; } @@ -1794,7 +1802,7 @@ void filelist_clear_ex(struct FileList *filelist, filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size); } - filelist_intern_free(&filelist->filelist_intern); + filelist_intern_free(filelist); filelist_direntryarr_free(&filelist->filelist); @@ -1822,7 +1830,7 @@ static void filelist_clear_main_files(FileList *filelist, filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size); } - const int removed_files = filelist_intern_free_main_files(&filelist->filelist_intern); + const int removed_files = filelist_intern_free_main_files(filelist); filelist->filelist.entries_num -= removed_files; filelist->filelist.entries_filtered_num = FILEDIR_NBR_ENTRIES_UNSET; @@ -1881,7 +1889,7 @@ void filelist_free(struct FileList *filelist) AssetLibrary *filelist_asset_library(FileList *filelist) { - return filelist->asset_library; + return reinterpret_cast<::AssetLibrary *>(filelist->asset_library); } void filelist_freelib(struct FileList *filelist) @@ -1897,11 +1905,15 @@ BlendHandle *filelist_lib(struct FileList *filelist) return filelist->libfiledata; } -static char *fileentry_uiname(const char *root, - const char *relpath, - const eFileSel_File_Types typeflag, - char *buff) +static const char *fileentry_uiname(const char *root, FileListInternEntry *entry, char *buff) { + if (entry->asset) { + const StringRefNull asset_name = entry->asset->get_name(); + return BLI_strdupn(asset_name.c_str(), asset_name.size()); + } + + const char *relpath = entry->relpath; + const eFileSel_File_Types typeflag = entry->typeflag; char *name = nullptr; if (typeflag & FILE_TYPE_FTFONT && !(typeflag & FILE_TYPE_BLENDERLIB)) { @@ -2042,10 +2054,7 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in ret->redirection_path = BLI_strdup(entry->redirection_path); } ret->id = entry->local_data.id; - ret->asset_data = entry->imported_asset_data ? entry->imported_asset_data : nullptr; - if (ret->id && (ret->asset_data == nullptr)) { - ret->asset_data = ret->id->asset_data; - } + ret->asset = reinterpret_cast<::AssetRepresentation *>(entry->asset); /* For some file types the preview is already available. */ if (entry->local_data.preview_image && BKE_previewimg_is_finished(entry->local_data.preview_image, ICON_SIZE_PREVIEW)) { @@ -2996,8 +3005,13 @@ static FileListInternEntry *filelist_readjob_list_lib_group_create(const int idc return entry; } -static void filelist_readjob_list_lib_add_datablock(ListBase *entries, - const BLODataBlockInfo *datablock_info, +/** + * \warning: This "steals" the asset metadata from \a datablock_info. Not great design but fixing + * this requires redesigning things on the caller side for proper ownership management. + */ +static void filelist_readjob_list_lib_add_datablock(FileList *filelist, + ListBase *entries, + BLODataBlockInfo *datablock_info, const bool prefix_relpath_with_group_name, const int idcode, const char *group_name) @@ -3010,21 +3024,29 @@ static void filelist_readjob_list_lib_add_datablock(ListBase *entries, entry->relpath = BLI_strdup(datablock_info->name); } entry->typeflag |= FILE_TYPE_BLENDERLIB; - if (datablock_info) { entry->blenderlib_has_no_preview = datablock_info->no_preview_found; if (datablock_info->asset_data) { entry->typeflag |= FILE_TYPE_ASSET; - /* Moves ownership! */ - entry->imported_asset_data = datablock_info->asset_data; + + if (filelist->asset_library) { + /** XXX Moving out the asset metadata like this isn't great. */ + std::unique_ptr metadata = BKE_asset_metadata_move_to_unique_ptr( + datablock_info->asset_data); + BKE_asset_metadata_free(&datablock_info->asset_data); + + entry->asset = &filelist->asset_library->add_external_asset(datablock_info->name, + std::move(metadata)); + } } } entry->blentype = idcode; BLI_addtail(entries, entry); } -static void filelist_readjob_list_lib_add_datablocks(ListBase *entries, +static void filelist_readjob_list_lib_add_datablocks(FileList *filelist, + ListBase *entries, LinkNode *datablock_infos, const bool prefix_relpath_with_group_name, const int idcode, @@ -3033,19 +3055,21 @@ static void filelist_readjob_list_lib_add_datablocks(ListBase *entries, for (LinkNode *ln = datablock_infos; ln; ln = ln->next) { struct BLODataBlockInfo *datablock_info = static_cast(ln->link); filelist_readjob_list_lib_add_datablock( - entries, datablock_info, prefix_relpath_with_group_name, idcode, group_name); + filelist, entries, datablock_info, prefix_relpath_with_group_name, idcode, group_name); } } static void filelist_readjob_list_lib_add_from_indexer_entries( + FileList *filelist, ListBase *entries, const FileIndexerEntries *indexer_entries, const bool prefix_relpath_with_group_name) { for (const LinkNode *ln = indexer_entries->entries; ln; ln = ln->next) { - const FileIndexerEntry *indexer_entry = (const FileIndexerEntry *)ln->link; + FileIndexerEntry *indexer_entry = static_cast(ln->link); const char *group_name = BKE_idtype_idcode_to_name(indexer_entry->idcode); - filelist_readjob_list_lib_add_datablock(entries, + filelist_readjob_list_lib_add_datablock(filelist, + entries, &indexer_entry->datablock_info, prefix_relpath_with_group_name, indexer_entry->idcode, @@ -3073,7 +3097,8 @@ typedef struct FileIndexer { void *user_data; } FileIndexer; -static int filelist_readjob_list_lib_populate_from_index(ListBase *entries, +static int filelist_readjob_list_lib_populate_from_index(FileList *filelist, + ListBase *entries, const ListLibOptions options, const int read_from_index, const FileIndexerEntries *indexer_entries) @@ -3085,11 +3110,12 @@ static int filelist_readjob_list_lib_populate_from_index(ListBase *entries, navigate_to_parent_len = 1; } - filelist_readjob_list_lib_add_from_indexer_entries(entries, indexer_entries, true); + filelist_readjob_list_lib_add_from_indexer_entries(filelist, entries, indexer_entries, true); return read_from_index + navigate_to_parent_len; } -static int filelist_readjob_list_lib(const char *root, +static int filelist_readjob_list_lib(FileList *filelist, + const char *root, ListBase *entries, const ListLibOptions options, FileIndexer *indexer_runtime) @@ -3128,7 +3154,7 @@ static int filelist_readjob_list_lib(const char *root, dir, &indexer_entries, &read_from_index, indexer_runtime->user_data); if (indexer_result == FILE_INDEXER_ENTRIES_LOADED) { int entries_read = filelist_readjob_list_lib_populate_from_index( - entries, options, read_from_index, &indexer_entries); + filelist, entries, options, read_from_index, &indexer_entries); ED_file_indexer_entries_clear(&indexer_entries); return entries_read; } @@ -3158,7 +3184,8 @@ static int filelist_readjob_list_lib(const char *root, const int idcode = groupname_to_code(group); LinkNode *datablock_infos = BLO_blendhandle_get_datablock_info( libfiledata, idcode, options & LIST_LIB_ASSETS_ONLY, &datablock_len); - filelist_readjob_list_lib_add_datablocks(entries, datablock_infos, false, idcode, group); + filelist_readjob_list_lib_add_datablocks( + filelist, entries, datablock_infos, false, idcode, group); BLI_linklist_freeN(datablock_infos); } else { @@ -3177,7 +3204,7 @@ static int filelist_readjob_list_lib(const char *root, LinkNode *group_datablock_infos = BLO_blendhandle_get_datablock_info( libfiledata, idcode, options & LIST_LIB_ASSETS_ONLY, &group_datablock_len); filelist_readjob_list_lib_add_datablocks( - entries, group_datablock_infos, true, idcode, group_name); + filelist, entries, group_datablock_infos, true, idcode, group_name); if (use_indexer) { ED_file_indexer_entries_extend_from_datablock_infos( &indexer_entries, group_datablock_infos, idcode); @@ -3529,7 +3556,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, list_lib_options |= LIST_LIB_ASSETS_ONLY; } entries_num = filelist_readjob_list_lib( - subdir, &entries, list_lib_options, &indexer_runtime); + filelist, subdir, &entries, list_lib_options, &indexer_runtime); if (entries_num > 0) { is_lib = true; } @@ -3550,7 +3577,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, MEM_freeN(entry->relpath); entry->relpath = BLI_strdup(dir + 2); /* + 2 to remove '//' * added by BLI_path_rel to rel_subdir. */ - entry->name = fileentry_uiname(root, entry->relpath, entry->typeflag, dir); + entry->name = fileentry_uiname(root, entry, dir); entry->free_name = true; if (filelist_readjob_should_recurse_into_entry( @@ -3626,20 +3653,6 @@ static void filelist_readjob_lib(FileListReadJob *job_params, filelist_readjob_do(true, job_params, stop, do_update, progress); } -static void filelist_asset_library_path(const FileListReadJob *job_params, - char r_library_root_path[FILE_MAX]) -{ - if (job_params->filelist->type == FILE_MAIN_ASSET) { - /* For the "Current File" library (#FILE_MAIN_ASSET) we get the asset library root path based - * on main. */ - BKE_asset_library_find_suitable_root_path_from_main(job_params->current_main, - r_library_root_path); - } - else { - BLI_strncpy(r_library_root_path, job_params->tmp_filelist->filelist.root, FILE_MAX); - } -} - /** * Load asset library data, which currently means loading the asset catalogs for the library. */ @@ -3657,12 +3670,10 @@ static void filelist_readjob_load_asset_library_data(FileListReadJob *job_params return; } - char library_root_path[FILE_MAX]; - filelist_asset_library_path(job_params, library_root_path); - /* Load asset catalogs, into the temp filelist for thread-safety. * #filelist_readjob_endjob() will move it into the real filelist. */ - tmp_filelist->asset_library = BKE_asset_library_load(library_root_path); + tmp_filelist->asset_library = BKE_asset_library_load(job_params->current_main, + *job_params->filelist->asset_library_ref); *do_update = true; } @@ -3699,6 +3710,9 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params, entry->local_data.preview_image = BKE_asset_metadata_preview_get_from_id(id_iter->asset_data, id_iter); entry->local_data.id = id_iter; + if (filelist->asset_library) { + entry->asset = &filelist->asset_library->add_local_id_asset(*id_iter); + } entries_num++; BLI_addtail(&tmp_entries, entry); } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 74f1b8e838a..95b87f06d96 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -950,7 +950,7 @@ static int /*eContextResult*/ file_context(const bContext *C, for (int file_index = 0; file_index < num_files_filtered; file_index++) { if (filelist_entry_is_selected(sfile->files, file_index)) { FileDirEntry *entry = filelist_file(sfile->files, file_index); - if (entry->asset_data) { + if (entry->asset) { CTX_data_list_add(result, &screen->id, &RNA_FileSelectEntry, entry); } } diff --git a/source/blender/makesdna/DNA_asset_types.h b/source/blender/makesdna/DNA_asset_types.h index 29795519719..d7e3bcfc919 100644 --- a/source/blender/makesdna/DNA_asset_types.h +++ b/source/blender/makesdna/DNA_asset_types.h @@ -42,6 +42,10 @@ typedef struct AssetFilterSettings { * more than that from the file. So pointers to other IDs or ID data are strictly forbidden. */ typedef struct AssetMetaData { +#ifdef __cplusplus + ~AssetMetaData(); +#endif + /** Runtime type, to reference event callbacks. Only valid for local assets. */ struct AssetTypeInfo *local_type_info; @@ -114,6 +118,8 @@ typedef struct AssetLibraryReference { } AssetLibraryReference; /** + * To be replaced by #AssetRepresentation! + * * Not part of the core design, we should try to get rid of it. Only needed to wrap FileDirEntry * into a type with PropertyGroup as base, so we can have an RNA collection of #AssetHandle's to * pass to the UI. diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 4bb92e6fcc5..d6d5f64a6a6 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1107,7 +1107,7 @@ typedef struct FileDirEntry { uint32_t uid; /* FileUID */ /* Name needs freeing if FILE_ENTRY_NAME_FREE is set. Otherwise this is a direct pointer to a * name buffer. */ - char *name; + const char *name; uint64_t size; int64_t time; @@ -1134,7 +1134,7 @@ typedef struct FileDirEntry { /** If this file represents an asset, its asset data is here. Note that we may show assets of * external files in which case this is set but not the id above. * Note comment for FileListInternEntry.local_data, the same applies here! */ - struct AssetMetaData *asset_data; + struct AssetRepresentation *asset; /* The icon_id for the preview image. */ int preview_icon_id; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index b2663b89333..b0311d63d44 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -540,6 +540,7 @@ static const EnumPropertyItem rna_enum_curve_display_handle_items[] = { # include "BLI_string.h" # include "BKE_anim_data.h" +# include "BKE_asset.h" # include "BKE_brush.h" # include "BKE_colortools.h" # include "BKE_context.h" @@ -2761,18 +2762,24 @@ static PointerRNA rna_FileBrowser_FileSelectEntry_asset_data_get(PointerRNA *ptr { const FileDirEntry *entry = ptr->data; + if (!entry->asset) { + return PointerRNA_NULL; + } + + AssetMetaData *asset_data = BKE_asset_representation_metadata_get(entry->asset); + /* Note that the owning ID of the RNA pointer (`ptr->owner_id`) has to be set carefully: * Local IDs (`entry->id`) own their asset metadata themselves. Asset metadata from other blend * files are owned by the file browser (`entry`). Only if this is set correctly, we can tell from * the metadata RNA pointer if the metadata is stored locally and can thus be edited or not. */ - if (entry->id) { + if (BKE_asset_representation_is_local_id(entry->asset)) { PointerRNA id_ptr; RNA_id_pointer_create(entry->id, &id_ptr); - return rna_pointer_inherit_refine(&id_ptr, &RNA_AssetMetaData, entry->asset_data); + return rna_pointer_inherit_refine(&id_ptr, &RNA_AssetMetaData, asset_data); } - return rna_pointer_inherit_refine(ptr, &RNA_AssetMetaData, entry->asset_data); + return rna_pointer_inherit_refine(ptr, &RNA_AssetMetaData, asset_data); } static int rna_FileBrowser_FileSelectEntry_name_editable(PointerRNA *ptr, const char **r_info) @@ -2782,7 +2789,7 @@ static int rna_FileBrowser_FileSelectEntry_name_editable(PointerRNA *ptr, const /* This actually always returns 0 (the name is never editable) but we want to get a disabled * message returned to `r_info` in some cases. */ - if (entry->asset_data) { + if (entry->asset) { PointerRNA asset_data_ptr = rna_FileBrowser_FileSelectEntry_asset_data_get(ptr); /* Get disabled hint from asset metadata polling. */ rna_AssetMetaData_editable(&asset_data_ptr, r_info); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 329e22c156a..3526a4349b5 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -1302,7 +1302,6 @@ bool WM_drag_is_ID_type(const struct wmDrag *drag, int idcode); * \note Does not store \a asset in any way, so it's fine to pass a temporary. */ wmDragAsset *WM_drag_create_asset_data(const struct AssetHandle *asset, - struct AssetMetaData *metadata, const char *path, int import_type); struct wmDragAsset *WM_drag_get_asset_data(const struct wmDrag *drag, int idcode); diff --git a/source/blender/windowmanager/intern/wm_dragdrop.cc b/source/blender/windowmanager/intern/wm_dragdrop.cc index fb63abed9e9..393149f20f5 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.cc +++ b/source/blender/windowmanager/intern/wm_dragdrop.cc @@ -556,15 +556,12 @@ bool WM_drag_is_ID_type(const wmDrag *drag, int idcode) return WM_drag_get_local_ID(drag, idcode) || WM_drag_get_asset_data(drag, idcode); } -wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset, - AssetMetaData *metadata, - const char *path, - int import_type) +wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset, const char *path, int import_type) { wmDragAsset *asset_drag = MEM_new(__func__); BLI_strncpy(asset_drag->name, ED_asset_handle_get_name(asset), sizeof(asset_drag->name)); - asset_drag->metadata = metadata; + asset_drag->metadata = ED_asset_handle_get_metadata(asset); asset_drag->path = path; asset_drag->id_type = ED_asset_handle_get_id_type(asset); asset_drag->import_type = import_type; @@ -733,12 +730,11 @@ void WM_drag_add_asset_list_item( drag_asset->asset_data.local_id = local_id; } else { - AssetMetaData *metadata = ED_asset_handle_get_metadata(asset); char asset_blend_path[FILE_MAX_LIBEXTRA]; ED_asset_handle_get_full_library_path(C, asset_library_ref, asset, asset_blend_path); drag_asset->is_external = true; drag_asset->asset_data.external_info = WM_drag_create_asset_data( - asset, metadata, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND); + asset, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND); } BLI_addtail(&drag->asset_items, drag_asset); } -- cgit v1.2.3 From 5291e4c358f4dd81d3822e54c2241472a8f6e436 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 9 Nov 2022 19:35:47 +0100 Subject: Cleanup: Remove unused class variable, added in previous commit --- source/blender/blenkernel/BKE_asset_library.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_asset_library.hh b/source/blender/blenkernel/BKE_asset_library.hh index b6a11a6b3f4..e4ad5b78c43 100644 --- a/source/blender/blenkernel/BKE_asset_library.hh +++ b/source/blender/blenkernel/BKE_asset_library.hh @@ -40,9 +40,6 @@ struct AssetLibrary { * for managing the "Save Catalog Changes" in the quit-confirmation dialog box. */ static bool save_catalogs_when_file_is_saved; - /** The directory representing the root of this library. */ - std::string root_path; - std::unique_ptr catalog_service; AssetLibrary(); -- cgit v1.2.3 From 8232cf5287445d21b7d6effb3f0e1ffb6df09adf Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Nov 2022 19:35:54 +0100 Subject: Fix T101669: Cycles artifacts in bump map baking After barycentric convention changes, the differentials used for bump mapping were wrong leading to artifacts with long thin triangles. --- intern/cycles/kernel/integrator/init_from_bake.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/intern/cycles/kernel/integrator/init_from_bake.h b/intern/cycles/kernel/integrator/init_from_bake.h index 667ba949760..cc3fbe3fe39 100644 --- a/intern/cycles/kernel/integrator/init_from_bake.h +++ b/intern/cycles/kernel/integrator/init_from_bake.h @@ -156,6 +156,13 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg, u = v; v = 1.0f - tmp - v; + const float tmpdx = dudx; + const float tmpdy = dudy; + dudx = dvdx; + dudy = dvdy; + dvdx = -tmpdx - dvdx; + dvdy = -tmpdy - dvdy; + /* Position and normal on triangle. */ const int object = kernel_data.bake.object_index; float3 P, Ng; -- cgit v1.2.3 From ad227e73f35dbe5b0c4a281ce471411e0ec97b87 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 9 Nov 2022 19:37:05 +0100 Subject: Cleanup: Link to documentation page for asset representation type --- source/blender/blenkernel/BKE_asset_representation.hh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_asset_representation.hh b/source/blender/blenkernel/BKE_asset_representation.hh index 0297e35c18c..4de63473113 100644 --- a/source/blender/blenkernel/BKE_asset_representation.hh +++ b/source/blender/blenkernel/BKE_asset_representation.hh @@ -19,9 +19,7 @@ namespace blender::bke { /** * \brief Abstraction to reference an asset, with necessary data for display & interaction. * - * #AssetRepresentation is the data-structure to store information about a single asset. It doesn't - * contain the asset itself, but information like the metadata and preview, as well as methods to - * interact with them. Think of it like a view on an asset. + * https://wiki.blender.org/wiki/Source/Architecture/Asset_System/Back_End#Asset_Representation */ class AssetRepresentation { friend class AssetLibrary; -- cgit v1.2.3 From 7f6521f8dc95f175eb09c77c26f5a3eb3dc7a3c0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Nov 2022 20:30:41 +0100 Subject: Fix T100883: crash with particle instancing and clumping Properly initialize clump curve mapping tables for duplis and other cases where this was missed by making a generic init/free function instead of duplicating the same logic in multiple places. Also fold lattice deform init into this. --- source/blender/blenkernel/BKE_particle.h | 8 +++- source/blender/blenkernel/intern/fluid.c | 14 ++---- source/blender/blenkernel/intern/object_dupli.cc | 8 +--- source/blender/blenkernel/intern/particle.c | 50 +++++++++++++++------- source/blender/blenkernel/intern/particle_system.c | 27 +++++------- .../draw/intern/draw_cache_impl_particles.c | 4 +- .../io/alembic/exporter/abc_writer_points.cc | 7 +-- source/blender/modifiers/intern/MOD_explode.c | 7 +-- .../modifiers/intern/MOD_particleinstance.c | 7 +-- .../blender/render/intern/texture_pointdensity.c | 14 ++---- 10 files changed, 69 insertions(+), 77 deletions(-) diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index a797aef73f6..05b9aca7544 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -291,7 +291,11 @@ void psys_set_current_num(struct Object *ob, int index); /* UNUSED */ // struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys); -struct LatticeDeformData *psys_create_lattice_deform_data(struct ParticleSimulationData *sim); +/** + * Initialize/free data for particle simulation evaluation. + */ +void psys_sim_data_init(struct ParticleSimulationData *sim); +void psys_sim_data_free(struct ParticleSimulationData *sim); /** * For a given evaluated particle system get its original. @@ -416,7 +420,7 @@ void psys_get_particle_on_path(struct ParticleSimulationData *sim, struct ParticleKey *state, bool vel); /** - * Gets particle's state at a time. + * Gets particle's state at a time. Must call psys_sim_data_init before this. * \return true if particle exists and can be seen and false if not. */ bool psys_get_particle_state(struct ParticleSimulationData *sim, diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index a3d2d73678c..c72f498cd5a 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -1532,18 +1532,8 @@ static void emit_from_particles(Object *flow_ob, sim.scene = scene; sim.ob = flow_ob; sim.psys = psys; - sim.psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); - /* prepare curvemapping tables */ - if ((psys->part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && psys->part->clumpcurve) { - BKE_curvemapping_changed_all(psys->part->clumpcurve); - } - if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve) { - BKE_curvemapping_changed_all(psys->part->roughcurve); - } - if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve) { - BKE_curvemapping_changed_all(psys->part->twistcurve); - } + psys_sim_data_init(&sim); /* initialize particle cache */ if (psys->part->type == PART_HAIR) { @@ -1684,6 +1674,8 @@ static void emit_from_particles(Object *flow_ob, if (particle_vel) { MEM_freeN(particle_vel); } + + psys_sim_data_free(&sim); } } diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index a41f7c8bce4..5efd44c620b 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -1390,7 +1390,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem RNG *rng = BLI_rng_new_srandom(31415926u + uint(psys->seed)); - psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); + psys_sim_data_init(&sim); /* Gather list of objects or single object. */ int totcollection = 0; @@ -1612,17 +1612,13 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem } BLI_rng_free(rng); + psys_sim_data_free(&sim); } /* Clean up. */ if (oblist) { MEM_freeN(oblist); } - - if (psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = nullptr; - } } static void make_duplis_particles(const DupliContext *ctx) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 4a0a09bcf56..6a277295efd 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -684,10 +684,13 @@ void psys_set_current_num(Object *ob, int index) } } -struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData *sim) +void psys_sim_data_init(ParticleSimulationData *sim) { - struct LatticeDeformData *lattice_deform_data = NULL; + ParticleSystem *psys = sim->psys; + ParticleSettings *part = psys->part; + /* Prepare lattice deform. */ + psys->lattice_deform_data = NULL; if (psys_in_edit_mode(sim->depsgraph, sim->psys) == 0) { Object *lattice = NULL; ModifierData *md = (ModifierData *)psys_get_modifier(sim->ob, sim->psys); @@ -699,19 +702,39 @@ struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData if (md->mode & mode) { LatticeModifierData *lmd = (LatticeModifierData *)md; lattice = lmd->object; - sim->psys->lattice_strength = lmd->strength; + psys->lattice_strength = lmd->strength; } break; } } if (lattice) { - lattice_deform_data = BKE_lattice_deform_data_create(lattice, NULL); + psys->lattice_deform_data = BKE_lattice_deform_data_create(lattice, NULL); } } - return lattice_deform_data; + /* Prepare curvemapping tables. */ + if ((part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && part->clumpcurve) { + BKE_curvemapping_init(part->clumpcurve); + } + if ((part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && part->roughcurve) { + BKE_curvemapping_init(part->roughcurve); + } + if ((part->child_flag & PART_CHILD_USE_TWIST_CURVE) && part->twistcurve) { + BKE_curvemapping_init(part->twistcurve); + } } + +void psys_sim_data_free(ParticleSimulationData *sim) +{ + ParticleSystem *psys = sim->psys; + + if (psys->lattice_deform_data) { + BKE_lattice_deform_data_destroy(psys->lattice_deform_data); + psys->lattice_deform_data = NULL; + } +} + void psys_disable_all(Object *ob) { ParticleSystem *psys = ob->particlesystem.first; @@ -2784,7 +2807,7 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx, ctx->cfra = cfra; ctx->editupdate = editupdate; - psys->lattice_deform_data = psys_create_lattice_deform_data(&ctx->sim); + psys_sim_data_init(&ctx->sim); /* cache all relevant vertex groups if they exist */ ctx->vg_length = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_LENGTH); @@ -3340,7 +3363,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re cache = psys->pathcache = psys_alloc_path_cache_buffers( &psys->pathcachebufs, totpart, segments + 1); - psys->lattice_deform_data = psys_create_lattice_deform_data(sim); + psys_sim_data_init(sim); ma = BKE_object_material_get(sim->ob, psys->part->omat); if (ma && (psys->part->draw_col == PART_DRAW_COL_MAT)) { copy_v3_v3(col, &ma->r); @@ -3507,10 +3530,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re psys->totcached = totpart; - if (psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - } + psys_sim_data_free(sim); if (vg_effector) { MEM_freeN(vg_effector); @@ -4867,6 +4887,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, } } } + bool psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *state, @@ -5225,7 +5246,7 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par sim.psys = psys; sim.psmd = psys_get_modifier(ob, psys); - psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); + psys_sim_data_init(&sim); if (psys->lattice_deform_data) { ParticleData *pa = psys->particles; @@ -5246,12 +5267,11 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par } } - BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - /* protect the applied shape */ psys->flag |= PSYS_EDITED; } + + psys_sim_data_free(&sim); } /* Draw Engine */ diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 72094f8cf04..d97a217a734 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -516,10 +516,7 @@ void psys_thread_context_free(ParticleThreadContext *ctx) MEM_freeN(ctx->vg_twist); } - if (ctx->sim.psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(ctx->sim.psys->lattice_deform_data); - ctx->sim.psys->lattice_deform_data = NULL; - } + psys_sim_data_free(&ctx->sim); /* distribution */ if (ctx->jit) { @@ -3557,12 +3554,12 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) invert_m4_m4(ob->world_to_object, ob->object_to_world); - psys->lattice_deform_data = psys_create_lattice_deform_data(sim); - if (psys->totpart == 0) { return; } + psys_sim_data_init(sim); + /* save new keys for elements if needed */ LOOP_PARTICLES { @@ -3596,6 +3593,8 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) zero_v3(root->co); } } + + psys_sim_data_free(sim); } /* Code for an adaptive time step based on the Courant-Friedrichs-Lewy @@ -4099,6 +4098,8 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_ disp = psys_get_current_display_percentage(psys, use_render_params); + psys_sim_data_init(sim); + LOOP_PARTICLES { psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra); @@ -4107,8 +4108,6 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_ pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1); } - psys->lattice_deform_data = psys_create_lattice_deform_data(sim); - dietime = pa->dietime; /* update alive status and push events */ @@ -4125,11 +4124,6 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_ pa->alive = PARS_ALIVE; } - if (psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - } - if (psys_frand(psys, p) > disp) { pa->flag |= PARS_NO_DISP; } @@ -4137,6 +4131,8 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_ pa->flag &= ~PARS_NO_DISP; } } + + psys_sim_data_free(sim); } static bool particles_has_flip(short parttype) @@ -4609,10 +4605,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_ update_children(sim, use_render_params); /* cleanup */ - if (psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - } + psys_sim_data_free(sim); } void psys_changed_type(Object *ob, ParticleSystem *psys) diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 8facea4333f..cddab74c46f 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -1346,7 +1346,7 @@ static void particle_batch_cache_ensure_pos(Object *object, sim.ob = object; sim.psys = psys; sim.psmd = psys_get_modifier(object, psys); - sim.psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); + psys_sim_data_init(&sim); GPU_VERTBUF_DISCARD_SAFE(point_cache->pos); @@ -1392,6 +1392,8 @@ static void particle_batch_cache_ensure_pos(Object *object, if (curr_point != psys->totpart) { GPU_vertbuf_data_resize(point_cache->pos, curr_point); } + + psys_sim_data_free(&sim); } static void drw_particle_update_ptcache_edit(Object *object_eval, diff --git a/source/blender/io/alembic/exporter/abc_writer_points.cc b/source/blender/io/alembic/exporter/abc_writer_points.cc index 6ec6f736818..9372bffc3ca 100644 --- a/source/blender/io/alembic/exporter/abc_writer_points.cc +++ b/source/blender/io/alembic/exporter/abc_writer_points.cc @@ -85,7 +85,7 @@ void ABCPointsWriter::do_write(HierarchyContext &context) sim.ob = context.object; sim.psys = psys; - psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); + psys_sim_data_init(&sim); uint64_t index = 0; for (int p = 0; p < psys->totpart; p++) { @@ -113,10 +113,7 @@ void ABCPointsWriter::do_write(HierarchyContext &context) ids.push_back(index++); } - if (psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = nullptr; - } + psys_sim_data_free(&sim); Alembic::Abc::P3fArraySample psample(points); Alembic::Abc::UInt64ArraySample idsample(ids); diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 96bf836fa4a..b0806fed91c 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -987,7 +987,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* getting back to object space */ invert_m4_m4(imat, ctx->object->object_to_world); - psmd->psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); + psys_sim_data_init(&sim); const MVert *mesh_verts = BKE_mesh_verts(mesh); MVert *explode_verts = BKE_mesh_verts_for_write(explode); @@ -1112,10 +1112,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, BKE_mesh_calc_edges_tessface(explode); BKE_mesh_convert_mfaces_to_mpolys(explode); - if (psmd->psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(psmd->psys->lattice_deform_data); - psmd->psys->lattice_deform_data = NULL; - } + psys_sim_data_free(&sim); return explode; } diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index f65f8bc4fb3..46e14dd6bfb 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -303,7 +303,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * maxedge += totedge; } - psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); + psys_sim_data_init(&sim); if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) { float min[3], max[3]; @@ -514,10 +514,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * p_skip++; } - if (psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - } + psys_sim_data_free(&sim); if (size) { MEM_freeN(size); diff --git a/source/blender/render/intern/texture_pointdensity.c b/source/blender/render/intern/texture_pointdensity.c index 5c31192f62a..09173aaa0e3 100644 --- a/source/blender/render/intern/texture_pointdensity.c +++ b/source/blender/render/intern/texture_pointdensity.c @@ -178,7 +178,7 @@ static void pointdensity_cache_psys( invert_m4_m4(ob->world_to_object, ob->object_to_world); total_particles = psys->totpart + psys->totchild; - psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); + psys_sim_data_init(&sim); pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6); pd->totpoints = total_particles; @@ -258,10 +258,7 @@ static void pointdensity_cache_psys( BLI_bvhtree_balance(pd->point_tree); - if (psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - } + psys_sim_data_free(&sim); } static void pointdensity_cache_vertex_color(PointDensity *pd, @@ -780,7 +777,7 @@ static void particle_system_minmax(Depsgraph *depsgraph, invert_m4_m4(imat, object->object_to_world); total_particles = psys->totpart + psys->totchild; - psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); + psys_sim_data_init(&sim); for (i = 0, pa = psys->particles; i < total_particles; i++, pa++) { float co_object[3], co_min[3], co_max[3]; @@ -796,10 +793,7 @@ static void particle_system_minmax(Depsgraph *depsgraph, minmax_v3v3_v3(min, max, co_max); } - if (psys->lattice_deform_data) { - BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - } + psys_sim_data_free(&sim); } void RE_point_density_cache(struct Depsgraph *depsgraph, PointDensity *pd) -- cgit v1.2.3 From bfc7653490f6a7f8f6e916fccefee63f1ff94699 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 9 Nov 2022 13:44:50 -0600 Subject: Fix T101972: Crash converting 1 or 2 point NURBS curve to Bezier The conversion is only able to handle NURBS curves with at least three points. This commit just avoids the crash for shorter curves. If this ends up confusing users, an error message could be added in the future. --- source/blender/geometry/intern/set_curve_type.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/geometry/intern/set_curve_type.cc b/source/blender/geometry/intern/set_curve_type.cc index 4233c62c7b3..e069732ca9b 100644 --- a/source/blender/geometry/intern/set_curve_type.cc +++ b/source/blender/geometry/intern/set_curve_type.cc @@ -257,7 +257,7 @@ static int to_bezier_size(const CurveType src_type, switch (src_type) { case CURVE_TYPE_NURBS: { if (is_nurbs_to_bezier_one_to_one(knots_mode)) { - return cyclic ? src_size : src_size - 2; + return cyclic ? src_size : std::max(1, src_size - 2); } return (src_size + 1) / 3; } @@ -392,6 +392,13 @@ static bke::CurvesGeometry convert_curves_to_bezier(const bke::CurvesGeometry &s const IndexRange src_points = src_curves.points_for_curve(i); const IndexRange dst_points = dst_curves.points_for_curve(i); const Span src_curve_positions = src_positions.slice(src_points); + if (dst_points.size() == 1) { + const float3 &position = src_positions[src_points.first()]; + dst_positions[dst_points.first()] = position; + dst_handles_l[dst_points.first()] = position; + dst_handles_r[dst_points.first()] = position; + continue; + } KnotsMode knots_mode = KnotsMode(src_knot_modes[i]); Span nurbs_positions = src_curve_positions; -- cgit v1.2.3 From cebea62b4770295ae35d98e1e9e85a457bc05922 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 9 Nov 2022 21:59:33 +0100 Subject: Fix T102256: Gamma Cross blend mode causes stripes Function `do_gammacross_effect_float` processed one color channel per loop iteration instead of whole pixel. --- source/blender/sequencer/intern/effects.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index 8469876ba25..6dd75031f3b 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -704,10 +704,13 @@ static void do_gammacross_effect_float( for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { - *rt = gammaCorrect(mfac * invGammaCorrect(*rt1) + fac * invGammaCorrect(*rt2)); - rt1++; - rt2++; - rt++; + rt[0] = gammaCorrect(mfac * invGammaCorrect(rt1[0]) + fac * invGammaCorrect(rt2[0])); + rt[1] = gammaCorrect(mfac * invGammaCorrect(rt1[1]) + fac * invGammaCorrect(rt2[1])); + rt[2] = gammaCorrect(mfac * invGammaCorrect(rt1[2]) + fac * invGammaCorrect(rt2[2])); + rt[3] = gammaCorrect(mfac * invGammaCorrect(rt1[3]) + fac * invGammaCorrect(rt2[3])); + rt1 += 4; + rt2+=4; + rt+=4; } } } -- cgit v1.2.3 From c8cec113536c6d931847b08b03745f90c34a0339 Mon Sep 17 00:00:00 2001 From: Leon Schittek Date: Wed, 9 Nov 2022 22:26:03 +0100 Subject: Fix T102385: Set frame node active after joining nodes Set the created frame node to be the active node when joining nodes with the `NODE_OT_join` operator. This behavior was unintentonaly changed in rB545fb528d5e1 when the operator's execute function was simplified by utilizing the node tree topology cache. Reviewed By: Hans Goudey Differential Revision: http://developer.blender.org/D16440 --- source/blender/editors/space_node/node_relationships.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 637c795d4d7..8eeba8727dc 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -1678,6 +1678,7 @@ static int node_join_exec(bContext *C, wmOperator * /*op*/) const Set selected_nodes = get_selected_nodes(ntree); bNode *frame_node = nodeAddStaticNode(C, &ntree, NODE_FRAME); + nodeSetActive(&ntree, frame_node); /* reset tags */ LISTBASE_FOREACH (bNode *, node, &ntree.nodes) { -- cgit v1.2.3 From b8fc7ed994049570da9d00589e2a952839670b73 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 9 Nov 2022 22:33:53 +0100 Subject: Fix incorrect forward declarations, causing warnings on Windows --- source/blender/blenkernel/BKE_asset_library.hh | 2 +- source/blender/blenkernel/BKE_asset_representation.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_asset_library.hh b/source/blender/blenkernel/BKE_asset_library.hh index e4ad5b78c43..f69847bd1ed 100644 --- a/source/blender/blenkernel/BKE_asset_library.hh +++ b/source/blender/blenkernel/BKE_asset_library.hh @@ -27,7 +27,7 @@ struct Main; namespace blender::bke { -struct AssetRepresentation; +class AssetRepresentation; /** * AssetLibrary provides access to an asset library's data. diff --git a/source/blender/blenkernel/BKE_asset_representation.hh b/source/blender/blenkernel/BKE_asset_representation.hh index 4de63473113..edaa5a203ba 100644 --- a/source/blender/blenkernel/BKE_asset_representation.hh +++ b/source/blender/blenkernel/BKE_asset_representation.hh @@ -22,7 +22,7 @@ namespace blender::bke { * https://wiki.blender.org/wiki/Source/Architecture/Asset_System/Back_End#Asset_Representation */ class AssetRepresentation { - friend class AssetLibrary; + friend struct AssetLibrary; struct ExternalAsset { std::string name; -- cgit v1.2.3 From 7c1ab77fa67252b6a0c61fb53f114c7c1916e364 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Wed, 9 Nov 2022 14:39:15 -0700 Subject: audaspace: Fix build error with MSVC 17.4+ `DeviceManager.h` uses `std::string` without explicitly including the `` header. While older MSVC implicitly included this header somewhere, the headers for 17.4+ do not leading to a build error. --- extern/audaspace/include/devices/DeviceManager.h | 1 + 1 file changed, 1 insertion(+) diff --git a/extern/audaspace/include/devices/DeviceManager.h b/extern/audaspace/include/devices/DeviceManager.h index 27a546630e8..fa84025478f 100644 --- a/extern/audaspace/include/devices/DeviceManager.h +++ b/extern/audaspace/include/devices/DeviceManager.h @@ -27,6 +27,7 @@ #include #include #include +#include AUD_NAMESPACE_BEGIN -- cgit v1.2.3 From 95077549c1fe079dd6fe46bf4af82b78c4905877 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 9 Nov 2022 22:50:18 +0100 Subject: Fix failure in recently added asset library tests Mistake in 1efc94bb2f7b. --- source/blender/blenkernel/intern/asset_library_service_test.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/asset_library_service_test.cc b/source/blender/blenkernel/intern/asset_library_service_test.cc index b68e47c9d0d..18fdcb80155 100644 --- a/source/blender/blenkernel/intern/asset_library_service_test.cc +++ b/source/blender/blenkernel/intern/asset_library_service_test.cc @@ -118,7 +118,8 @@ TEST_F(AssetLibraryServiceTest, library_from_reference) "the current file library"; Main dummy_main{}; - BLI_strncpy(dummy_main.filepath, asset_library_root_.c_str(), sizeof(dummy_main.filepath)); + std::string dummy_filepath = asset_library_root_ + SEP + "dummy.blend"; + BLI_strncpy(dummy_main.filepath, dummy_filepath.c_str(), sizeof(dummy_main.filepath)); EXPECT_EQ(lib, service->get_asset_library(&dummy_main, ref)) << "Getting the local (current file) reference with a main saved on disk should return " "the an asset library for this directory"; -- cgit v1.2.3 From 32757b2429a0939dd68ddb79824ea7fd2cad1cd4 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 9 Nov 2022 23:04:24 +0100 Subject: Fix uninitialized variable use in asset metadata test Wasn't an issue until 1efc94bb2f7b added a destructor, which would attempt to destruct variables at uninitialized memory. --- source/blender/blenkernel/intern/asset_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/asset_test.cc b/source/blender/blenkernel/intern/asset_test.cc index fa8769862a8..5ff65054926 100644 --- a/source/blender/blenkernel/intern/asset_test.cc +++ b/source/blender/blenkernel/intern/asset_test.cc @@ -13,7 +13,7 @@ namespace blender::bke::tests { TEST(AssetMetadataTest, set_catalog_id) { - AssetMetaData meta; + AssetMetaData meta{}; const bUUID uuid = BLI_uuid_generate_random(); /* Test trivial values. */ -- cgit v1.2.3 From d49dec896aaae5e2cdb5f2e2926f3bd010f4a0fe Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Wed, 9 Nov 2022 23:09:56 +0100 Subject: Attempt to fix build error on Windows Was failing since 1efc94bb2f7b, probably because some include uses `std::min()`/`std::max()` which messes with the windows min/max defines. --- source/blender/editors/space_file/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt index 688aa846c30..76564f38da8 100644 --- a/source/blender/editors/space_file/CMakeLists.txt +++ b/source/blender/editors/space_file/CMakeLists.txt @@ -46,6 +46,10 @@ set(LIB bf_blenkernel ) +if(WIN32) + add_definitions(-DNOMINMAX) +endif() + if(WITH_HEADLESS) add_definitions(-DWITH_HEADLESS) else() -- cgit v1.2.3