Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_asset.h19
-rw-r--r--source/blender/blenkernel/BKE_asset_library.h40
-rw-r--r--source/blender/blenkernel/BKE_asset_library.hh80
-rw-r--r--source/blender/blenkernel/BKE_asset_representation.hh64
-rw-r--r--source/blender/blenkernel/BKE_particle.h8
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/asset.cc28
-rw-r--r--source/blender/blenkernel/intern/asset_catalog.cc9
-rw-r--r--source/blender/blenkernel/intern/asset_library.cc90
-rw-r--r--source/blender/blenkernel/intern/asset_library_service.cc25
-rw-r--r--source/blender/blenkernel/intern/asset_library_service.hh8
-rw-r--r--source/blender/blenkernel/intern/asset_library_service_test.cc23
-rw-r--r--source/blender/blenkernel/intern/asset_representation.cc98
-rw-r--r--source/blender/blenkernel/intern/asset_test.cc2
-rw-r--r--source/blender/blenkernel/intern/context.c2
-rw-r--r--source/blender/blenkernel/intern/fluid.c14
-rw-r--r--source/blender/blenkernel/intern/lib_id_delete.c10
-rw-r--r--source/blender/blenkernel/intern/material.c47
-rw-r--r--source/blender/blenkernel/intern/object_dupli.cc8
-rw-r--r--source/blender/blenkernel/intern/particle.c50
-rw-r--r--source/blender/blenkernel/intern/particle_system.c27
21 files changed, 500 insertions, 154 deletions
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 <memory>
+
+[[nodiscard]] std::unique_ptr<AssetMetaData> 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..f69847bd1ed 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,11 +22,18 @@
#include <memory>
+struct AssetLibraryReference;
+struct Main;
+
namespace blender::bke {
+class 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,
@@ -35,12 +45,25 @@ struct AssetLibrary {
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<AssetMetaData> 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.
*
* No-op if the catalog cannot be found. This could be the kind of "the
@@ -53,8 +76,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<std::unique_ptr<AssetRepresentation>> asset_storage_;
+
+ std::optional<int> find_asset_index(const AssetRepresentation &asset);
};
Vector<AssetLibraryReference> all_valid_asset_library_refs();
@@ -64,6 +106,40 @@ Vector<AssetLibraryReference> 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..edaa5a203ba
--- /dev/null
+++ b/source/blender/blenkernel/BKE_asset_representation.hh
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup bke
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "BLI_string_ref.hh"
+
+struct AssetMetaData;
+struct ID;
+
+namespace blender::bke {
+
+/**
+ * \brief Abstraction to reference an asset, with necessary data for display & interaction.
+ *
+ * https://wiki.blender.org/wiki/Source/Architecture/Asset_System/Back_End#Asset_Representation
+ */
+class AssetRepresentation {
+ friend struct AssetLibrary;
+
+ struct ExternalAsset {
+ std::string name;
+ std::unique_ptr<AssetMetaData> 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<AssetMetaData> 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/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/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<AssetMetaData>(__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<AssetMetaData> BKE_asset_metadata_move_to_unique_ptr(AssetMetaData *asset_data)
+{
+ std::unique_ptr unique_asset_data = std::make_unique<AssetMetaData>(*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 <memory>
#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<AssetCatalogService>())
@@ -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<AssetCatalogService>(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<AssetMetaData> metadata)
+{
+ asset_storage_.append(std::make_unique<AssetRepresentation>(name, std::move(metadata)));
+ return *asset_storage_.last();
+}
+
+AssetRepresentation &AssetLibrary::add_local_id_asset(ID &id)
+{
+ asset_storage_.append(std::make_unique<AssetRepresentation>(id));
+ return *asset_storage_.last();
+}
+
+std::optional<int> 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<int> 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<AssetRepresentation *> 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<void(AssetLibrary &)> 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 <memory>
+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<void(AssetLibrary &)> fn) const;
+
protected:
static std::unique_ptr<AssetLibraryService> instance_;
/* Mapping absolute path of the library's top-level directory to the AssetLibrary instance. */
Map<std::string, AssetLibraryPtr> 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..18fdcb80155 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,26 @@ 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{};
+ 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";
+}
+
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 <stdexcept>
+
+#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<AssetMetaData> 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<const bke::AssetRepresentation *>(
+ asset_handle);
+ return asset->get_name().c_str();
+}
+
+AssetMetaData *BKE_asset_representation_metadata_get(const AssetRepresentation *asset_handle)
+{
+ const bke::AssetRepresentation *asset = reinterpret_cast<const bke::AssetRepresentation *>(
+ asset_handle);
+ return &asset->get_metadata();
+}
+
+bool BKE_asset_representation_is_local_id(const AssetRepresentation *asset_handle)
+{
+ const bke::AssetRepresentation *asset = reinterpret_cast<const bke::AssetRepresentation *>(
+ asset_handle);
+ return asset->is_local_id();
+}
+
+/** \} */
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. */
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/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/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/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/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)