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/intern')
-rw-r--r--source/blender/blenkernel/intern/appdir.c26
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/curve.c40
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c2
-rw-r--r--source/blender/blenkernel/intern/deform.c4
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c32
-rw-r--r--source/blender/blenkernel/intern/fcurve.c2
-rw-r--r--source/blender/blenkernel/intern/fluid.c119
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c2
-rw-r--r--source/blender/blenkernel/intern/key.c10
-rw-r--r--source/blender/blenkernel/intern/lib_override.c65
-rw-r--r--source/blender/blenkernel/intern/mask.c2
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c4
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c4
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c2
-rw-r--r--source/blender/blenkernel/intern/multires.c2
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.c2
-rw-r--r--source/blender/blenkernel/intern/node_tree_multi_function.cc91
-rw-r--r--source/blender/blenkernel/intern/object_deform.c2
-rw-r--r--source/blender/blenkernel/intern/ocean.c8
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c1
-rw-r--r--source/blender/blenkernel/intern/pbvh.c2
-rw-r--r--source/blender/blenkernel/intern/pointcache.c46
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c6
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c16
-rw-r--r--source/blender/blenkernel/intern/sequencer.c60
-rw-r--r--source/blender/blenkernel/intern/simulation.cc369
-rw-r--r--source/blender/blenkernel/intern/undo_system.c4
30 files changed, 747 insertions, 182 deletions
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 58337bcf488..2cc715464ad 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -56,7 +56,7 @@
# ifdef WITH_BINRELOC
# include "binreloc.h"
# endif
-/* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
+/* #mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
# include <unistd.h>
#endif /* WIN32 */
@@ -120,7 +120,7 @@ static char *blender_version_decimal(const int ver)
}
/**
- * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath,
+ * Concatenates path_base, (optional) path_sep and (optional) folder_name into \a targetpath,
* returning true if result points to a directory.
*/
static bool test_path(char *targetpath,
@@ -138,14 +138,14 @@ static bool test_path(char *targetpath,
BLI_strncpy(tmppath, path_base, sizeof(tmppath));
}
- /* rare cases folder_name is omitted (when looking for ~/.config/blender/2.xx dir only) */
+ /* Rare cases folder_name is omitted (when looking for `~/.config/blender/2.xx` dir only). */
if (folder_name) {
BLI_join_dirfile(targetpath, targetpath_len, tmppath, folder_name);
}
else {
BLI_strncpy(targetpath, tmppath, targetpath_len);
}
- /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
+ /* FIXME: why is "//" on front of \a tmppath expanded to "/" (by BLI_join_dirfile)
* if folder_name is specified but not otherwise? */
if (BLI_is_dir(targetpath)) {
@@ -190,7 +190,7 @@ static bool test_env_path(char *path, const char *envvar)
/**
* Constructs in \a targetpath the name of a directory relative to a version-specific
- * subdirectory in the parent directory of the Blender executable.
+ * sub-directory in the parent directory of the Blender executable.
*
* \param targetpath: String to return path
* \param folder_name: Optional folder name within version-specific directory
@@ -307,7 +307,7 @@ static bool get_path_environment_notest(char *targetpath,
* \param targetpath: String to return path
* \param folder_name: default name of folder within user area
* \param subfolder_name: optional name of subfolder within folder
- * \param ver: Blender version, used to construct a subdirectory name
+ * \param ver: Blender version, used to construct a sub-directory name
* \return true if it was able to construct such a path.
*/
static bool get_path_user(char *targetpath,
@@ -350,8 +350,8 @@ static bool get_path_user(char *targetpath,
*
* \param targetpath: String to return path
* \param folder_name: default name of folder within installation area
- * \param subfolder_name: optional name of subfolder within folder
- * \param ver: Blender version, used to construct a subdirectory name
+ * \param subfolder_name: optional name of sub-folder within folder
+ * \param ver: Blender version, used to construct a sub-directory name
* \return true if it was able to construct such a path.
*/
static bool get_path_system(char *targetpath,
@@ -635,7 +635,7 @@ const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, con
* adds the correct extension (.com .exe etc) from
* $PATHEXT if necessary. Also on Windows it translates
* the name to its 8.3 version to prevent problems with
- * spaces and stuff. Final result is returned in fullname.
+ * spaces and stuff. Final result is returned in \a fullname.
*
* \param fullname: The full path and full name of the executable
* (must be FILE_MAX minimum)
@@ -975,7 +975,7 @@ static void where_is_temp(char *fullname, char *basename, const size_t maxlen, c
/**
* Sets btempdir_base to userdir if specified and is a valid directory, otherwise
* chooses a suitable OS-specific temporary directory.
- * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base.
+ * Sets btempdir_session to a #mkdtemp generated sub-dir of btempdir_base.
*
* \note On Window userdir will be set to the temporary directory!
*/
@@ -1019,7 +1019,11 @@ void BKE_tempdir_session_purge(void)
}
/* Gets a good default directory for fonts */
-bool BKE_appdir_font_folder_default(char *dir)
+
+bool BKE_appdir_font_folder_default(
+ /* This parameter can only be `const` on non-windows platforms.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ char *dir)
{
bool success = false;
#ifdef WIN32
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 7c8c1cf6653..f45cd5b679a 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -1037,7 +1037,7 @@ static void cloth_free_errorsprings(Cloth *cloth,
}
BLI_INLINE void cloth_bend_poly_dir(
- ClothVertex *verts, int i, int j, int *inds, int len, float r_dir[3])
+ ClothVertex *verts, int i, int j, const int *inds, int len, float r_dir[3])
{
float cent[3] = {0};
float fact = 1.0f / len;
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index c894534c504..e9e44ac05e5 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -1157,7 +1157,7 @@ void BKE_nurb_knot_calc_v(Nurb *nu)
}
static void basisNurb(
- float t, short order, int pnts, float *knots, float *basis, int *start, int *end)
+ float t, short order, int pnts, const float *knots, float *basis, int *start, int *end)
{
float d, e;
int i, i1 = 0, i2 = 0, j, orderpluspnts, opp2, o2;
@@ -3560,8 +3560,13 @@ static void free_arrays(void *buffer)
}
/* computes in which direction to change h[i] to satisfy conditions better */
-static float bezier_relax_direction(
- float *a, float *b, float *c, float *d, float *h, int i, int count)
+static float bezier_relax_direction(const float *a,
+ const float *b,
+ const float *c,
+ const float *d,
+ const float *h,
+ int i,
+ int count)
{
/* current deviation between sides of the equation */
float state = a[i] * h[(i + count - 1) % count] + b[i] * h[i] + c[i] * h[(i + 1) % count] - d[i];
@@ -3577,8 +3582,15 @@ static void bezier_lock_unknown(float *a, float *b, float *c, float *d, int i, f
d[i] = value;
}
-static void bezier_restore_equation(
- float *a, float *b, float *c, float *d, float *a0, float *b0, float *c0, float *d0, int i)
+static void bezier_restore_equation(float *a,
+ float *b,
+ float *c,
+ float *d,
+ const float *a0,
+ const float *b0,
+ const float *c0,
+ const float *d0,
+ int i)
{
a[i] = a0[i];
b[i] = b0[i];
@@ -3586,8 +3598,14 @@ static void bezier_restore_equation(
d[i] = d0[i];
}
-static bool tridiagonal_solve_with_limits(
- float *a, float *b, float *c, float *d, float *h, float *hmin, float *hmax, int solve_count)
+static bool tridiagonal_solve_with_limits(float *a,
+ float *b,
+ float *c,
+ float *d,
+ float *h,
+ const float *hmin,
+ const float *hmax,
+ int solve_count)
{
float *a0, *b0, *c0, *d0;
float **arrays[] = {&a0, &b0, &c0, &d0, NULL};
@@ -3726,7 +3744,7 @@ static bool tridiagonal_solve_with_limits(
/* clang-format on */
static void bezier_eq_continuous(
- float *a, float *b, float *c, float *d, float *dy, float *l, int i)
+ float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
{
a[i] = l[i] * l[i];
b[i] = 2.0f * (l[i] + 1);
@@ -3735,7 +3753,7 @@ static void bezier_eq_continuous(
}
static void bezier_eq_noaccel_right(
- float *a, float *b, float *c, float *d, float *dy, float *l, int i)
+ float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
{
a[i] = 0.0f;
b[i] = 2.0f;
@@ -3744,7 +3762,7 @@ static void bezier_eq_noaccel_right(
}
static void bezier_eq_noaccel_left(
- float *a, float *b, float *c, float *d, float *dy, float *l, int i)
+ float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
{
a[i] = l[i] * l[i];
b[i] = 2.0f * l[i];
@@ -4823,7 +4841,7 @@ float (*BKE_curve_nurbs_key_vert_coords_alloc(ListBase *lb, float *key, int *r_v
return cos;
}
-void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, float *key)
+void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, const float *key)
{
Nurb *nu;
int i;
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 48e0ee50d43..9bdd80fd668 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -562,7 +562,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map
CustomData *cd_dst,
const bool use_dupref_dst,
const int tolayers,
- bool *use_layers_src,
+ const bool *use_layers_src,
const int num_layers_src,
cd_datatransfer_interp interp,
void *interp_data)
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index b97935d57f2..98fc5f9a23a 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -249,7 +249,7 @@ void BKE_defvert_sync_mapped(MDeformVert *dvert_dst,
/**
* be sure all flip_map values are valid
*/
-void BKE_defvert_remap(MDeformVert *dvert, int *map, const int map_len)
+void BKE_defvert_remap(MDeformVert *dvert, const int *map, const int map_len)
{
MDeformWeight *dw = dvert->dw;
unsigned int i;
@@ -1184,7 +1184,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
CustomData *cd_dst,
const bool UNUSED(use_dupref_dst),
const int tolayers,
- bool *use_layers_src,
+ const bool *use_layers_src,
const int num_layers_src)
{
int idx_src;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 2e1fa519284..b9279ace39f 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -588,7 +588,7 @@ static bool boundsIntersectDist(Bounds3D *b1, Bounds3D *b2, const float dist)
}
/* check whether bounds intersects a point with given radius */
-static bool boundIntersectPoint(Bounds3D *b, float point[3], const float radius)
+static bool boundIntersectPoint(Bounds3D *b, const float point[3], const float radius)
{
if (!b->valid) {
return false;
@@ -4780,13 +4780,16 @@ static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata,
}
}
-static int dynamicPaint_paintSinglePoint(Depsgraph *depsgraph,
- DynamicPaintSurface *surface,
- float *pointCoord,
- DynamicPaintBrushSettings *brush,
- Object *brushOb,
- Scene *scene,
- float timescale)
+static int dynamicPaint_paintSinglePoint(
+ Depsgraph *depsgraph,
+ DynamicPaintSurface *surface,
+ /* Cannot be const, because it is assigned to non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ float *pointCoord,
+ DynamicPaintBrushSettings *brush,
+ Object *brushOb,
+ Scene *scene,
+ float timescale)
{
PaintSurfaceData *sData = surface->data;
float brush_radius = brush->paint_distance * surface->radius_scale;
@@ -5456,11 +5459,14 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata,
}
}
-static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface,
- float *force,
- PaintPoint *prevPoint,
- float timescale,
- float steps)
+static void dynamicPaint_doEffectStep(
+ DynamicPaintSurface *surface,
+ /* Cannot be const, because it is assigned to non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ float *force,
+ PaintPoint *prevPoint,
+ float timescale,
+ float steps)
{
PaintSurfaceData *sData = surface->data;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index bc14f525c2c..746aff1697c 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1277,7 +1277,7 @@ short test_time_fcurve(FCurve *fcu)
* than the horizontal distance between (v1-v4).
* This is to prevent curve loops.
*/
-void correct_bezpart(float v1[2], float v2[2], float v3[2], float v4[2])
+void correct_bezpart(const float v1[2], float v2[2], float v3[2], const float v4[2])
{
float h1[2], h2[2], len1, len2, len, fac;
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 1f748487841..52a3521189b 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -137,9 +137,9 @@ bool BKE_fluid_reallocate_fluid(FluidDomainSettings *fds, int res[3], int free_o
void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
int o_res[3],
int n_res[3],
- int o_min[3],
- int n_min[3],
- int o_max[3],
+ const int o_min[3],
+ const int n_min[3],
+ const int o_max[3],
int o_shift[3],
int n_shift[3])
{
@@ -491,6 +491,17 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds,
fds->cell_size[2] /= (float)fds->base_res[2];
}
+static void update_final_gravity(FluidDomainSettings *fds, Scene *scene)
+{
+ if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
+ copy_v3_v3(fds->gravity_final, scene->physics_settings.gravity);
+ }
+ else {
+ copy_v3_v3(fds->gravity_final, fds->gravity);
+ }
+ mul_v3_fl(fds->gravity_final, fds->effector_weights->global_gravity);
+}
+
static bool BKE_fluid_modifier_init(
FluidModifierData *fmd, Depsgraph *depsgraph, Object *ob, Scene *scene, Mesh *me)
{
@@ -502,10 +513,7 @@ static bool BKE_fluid_modifier_init(
/* Set domain dimensions from mesh. */
manta_set_domain_from_mesh(fds, ob, me, true);
/* Set domain gravity, use global gravity if enabled. */
- if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
- copy_v3_v3(fds->gravity, scene->physics_settings.gravity);
- }
- mul_v3_fl(fds->gravity, fds->effector_weights->global_gravity);
+ update_final_gravity(fds, scene);
/* Reset domain values. */
zero_v3_int(fds->shift);
zero_v3(fds->shift_f);
@@ -559,7 +567,7 @@ static bool BKE_fluid_modifier_init(
// forward declaration
static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *view_layer);
static float calc_voxel_transp(
- float *result, float *input, int res[3], int *pixel, float *t_ray, float correct);
+ float *result, const float *input, int res[3], int *pixel, float *t_ray, float correct);
static void update_distances(int index,
float *fesh_distances,
BVHTreeFromMesh *tree_data,
@@ -594,8 +602,8 @@ static int get_light(ViewLayer *view_layer, float *light)
static void clamp_bounds_in_domain(FluidDomainSettings *fds,
int min[3],
int max[3],
- float *min_vel,
- float *max_vel,
+ const float *min_vel,
+ const float *max_vel,
int margin,
float dt)
{
@@ -1830,7 +1838,7 @@ static void sample_mesh(FluidFlowSettings *ffs,
float *velocity_map,
int index,
const int base_res[3],
- float flow_center[3],
+ const float flow_center[3],
BVHTreeFromMesh *tree_data,
const float ray_start[3],
const float *vert_vel,
@@ -3328,17 +3336,13 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obj
mverts->co[1] = manta_liquid_get_vertex_y_at(fds->fluid, i);
mverts->co[2] = manta_liquid_get_vertex_z_at(fds->fluid, i);
- /* If reading raw data directly from manta, normalize now (e.g. during replay mode).
- * If reading data from files from disk, omit this normalization. */
- if (!manta_liquid_mesh_from_file(fds->fluid)) {
- // normalize to unit cube around 0
- mverts->co[0] -= ((float)fds->res[0] * fds->mesh_scale) * 0.5f;
- mverts->co[1] -= ((float)fds->res[1] * fds->mesh_scale) * 0.5f;
- mverts->co[2] -= ((float)fds->res[2] * fds->mesh_scale) * 0.5f;
- mverts->co[0] *= fds->dx / fds->mesh_scale;
- mverts->co[1] *= fds->dx / fds->mesh_scale;
- mverts->co[2] *= fds->dx / fds->mesh_scale;
- }
+ /* Adjust coordinates from Mantaflow to match viewport scaling. */
+ float tmp[3] = {(float)fds->res[0], (float)fds->res[1], (float)fds->res[2]};
+ /* Scale to unit cube around 0. */
+ mul_v3_fl(tmp, fds->mesh_scale * 0.5f);
+ sub_v3_v3(mverts->co, tmp);
+ /* Apply scaling of domain object. */
+ mul_v3_fl(mverts->co, fds->dx / fds->mesh_scale);
mul_v3_v3(mverts->co, co_scale);
add_v3_v3(mverts->co, co_offset);
@@ -3808,10 +3812,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
fds->time_per_frame = 0;
/* Ensure that gravity is copied over every frame (could be keyframed). */
- if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
- copy_v3_v3(fds->gravity, scene->physics_settings.gravity);
- mul_v3_fl(fds->gravity, fds->effector_weights->global_gravity);
- }
+ update_final_gravity(fds, scene);
int next_frame = scene_framenr + 1;
int prev_frame = scene_framenr - 1;
@@ -4118,43 +4119,47 @@ static void BKE_fluid_modifier_process(
struct Mesh *BKE_fluid_modifier_do(
FluidModifierData *fmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *me)
{
- /* Lock so preview render does not read smoke data while it gets modified. */
- if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
- BLI_rw_mutex_lock(fmd->domain->fluid_mutex, THREAD_LOCK_WRITE);
- }
-
- BKE_fluid_modifier_process(fmd, depsgraph, scene, ob, me);
-
- if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
- BLI_rw_mutex_unlock(fmd->domain->fluid_mutex);
- }
-
/* Optimization: Do not update viewport during bakes (except in replay mode)
* Reason: UI is locked and updated liquid / smoke geometry is not visible anyways. */
bool needs_viewport_update = false;
- if (fmd->domain) {
- FluidDomainSettings *fds = fmd->domain;
- /* Always update viewport in cache replay mode. */
- if (fds->cache_type == FLUID_DOMAIN_CACHE_REPLAY ||
- fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
- needs_viewport_update = true;
+ /* Optimization: Only process modifier if object is not being altered. */
+ if (!G.moving) {
+ /* Lock so preview render does not read smoke data while it gets modified. */
+ if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
+ BLI_rw_mutex_lock(fmd->domain->fluid_mutex, THREAD_LOCK_WRITE);
}
- /* In other cache modes, only update the viewport when no bake is going on. */
- else {
- bool with_mesh;
- with_mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
- bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
- baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA;
- baking_noise = fds->cache_flag & FLUID_DOMAIN_BAKING_NOISE;
- baking_mesh = fds->cache_flag & FLUID_DOMAIN_BAKING_MESH;
- baking_particles = fds->cache_flag & FLUID_DOMAIN_BAKING_PARTICLES;
- baking_guide = fds->cache_flag & FLUID_DOMAIN_BAKING_GUIDE;
-
- if (with_mesh && !baking_data && !baking_noise && !baking_mesh && !baking_particles &&
- !baking_guide) {
+
+ BKE_fluid_modifier_process(fmd, depsgraph, scene, ob, me);
+
+ if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
+ BLI_rw_mutex_unlock(fmd->domain->fluid_mutex);
+ }
+
+ if (fmd->domain) {
+ FluidDomainSettings *fds = fmd->domain;
+
+ /* Always update viewport in cache replay mode. */
+ if (fds->cache_type == FLUID_DOMAIN_CACHE_REPLAY ||
+ fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
needs_viewport_update = true;
}
+ /* In other cache modes, only update the viewport when no bake is going on. */
+ else {
+ bool with_mesh;
+ with_mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
+ bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
+ baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA;
+ baking_noise = fds->cache_flag & FLUID_DOMAIN_BAKING_NOISE;
+ baking_mesh = fds->cache_flag & FLUID_DOMAIN_BAKING_MESH;
+ baking_particles = fds->cache_flag & FLUID_DOMAIN_BAKING_PARTICLES;
+ baking_guide = fds->cache_flag & FLUID_DOMAIN_BAKING_GUIDE;
+
+ if (with_mesh && !baking_data && !baking_noise && !baking_mesh && !baking_particles &&
+ !baking_guide) {
+ needs_viewport_update = true;
+ }
+ }
}
}
@@ -4196,7 +4201,7 @@ struct Mesh *BKE_fluid_modifier_do(
}
static float calc_voxel_transp(
- float *result, float *input, int res[3], int *pixel, float *t_ray, float correct)
+ float *result, const float *input, int res[3], int *pixel, float *t_ray, float correct)
{
const size_t index = manta_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]);
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index dfb0fff1239..b92f86d7aea 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -1146,7 +1146,7 @@ void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points,
static void gpencil_calc_stroke_fill_uv(const float (*points2d)[2],
bGPDstroke *gps,
const float minv[2],
- float maxv[2],
+ const float maxv[2],
float (*r_uv)[2])
{
const float s = sin(gps->uv_rotation);
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index af8ab22e14b..46a41df0391 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -529,7 +529,13 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
return 0;
}
-static void flerp(int tot, float *in, float *f0, float *f1, float *f2, float *f3, float *t)
+static void flerp(int tot,
+ float *in,
+ const float *f0,
+ const float *f1,
+ const float *f2,
+ const float *f3,
+ const float *t)
{
int a;
@@ -538,7 +544,7 @@ static void flerp(int tot, float *in, float *f0, float *f1, float *f2, float *f3
}
}
-static void rel_flerp(int tot, float *in, float *ref, float *out, float fac)
+static void rel_flerp(int tot, float *in, const float *ref, const float *out, float fac)
{
int a;
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 457d096f983..58856729f24 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -38,6 +38,7 @@
#include "BKE_key.h"
#include "BKE_lib_id.h"
#include "BKE_lib_override.h"
+#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
@@ -66,20 +67,6 @@ static void lib_override_library_property_clear(IDOverrideLibraryProperty *op);
static void lib_override_library_property_operation_clear(
IDOverrideLibraryPropertyOperation *opop);
-/* Temp, for until library override is ready and tested enough to go 'public',
- * we hide it by default in UI and such. */
-static bool _lib_override_library_enabled = true;
-
-void BKE_lib_override_library_enable(const bool do_enable)
-{
- _lib_override_library_enabled = do_enable;
-}
-
-bool BKE_lib_override_library_is_enabled()
-{
- return _lib_override_library_enabled;
-}
-
/** Initialize empty overriding of \a reference_id by \a local_id. */
IDOverrideLibrary *BKE_lib_override_library_init(ID *local_id, ID *reference_id)
{
@@ -368,6 +355,56 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
return success;
}
+static bool lib_override_hierarchy_recursive_tag(Main *bmain, ID *id)
+{
+ MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id);
+
+ /* This way we won't process again that ID should we encounter it again through another
+ * relationship hierarchy.
+ * Note that this does not free any memory from relations, so we can still use the entries.
+ */
+ BKE_main_relations_ID_remove(bmain, id);
+
+ for (; entry != NULL; entry = entry->next) {
+ /* We only consider IDs from the same library. */
+ if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) {
+ if (lib_override_hierarchy_recursive_tag(bmain, *entry->id_pointer)) {
+ id->tag |= LIB_TAG_DOIT;
+ }
+ }
+ }
+
+ return (id->tag & LIB_TAG_DOIT) != 0;
+}
+
+/**
+ * Tag all IDs in given \a bmain that use (depends on) given \a id_root ID.
+ *
+ * This will include all local IDs, and all IDs from the same library as the \a id_root.
+ *
+ * \param id_root The root of the hierarchy of dependencies to be tagged.
+ * \param do_create_main_relashionships Whether main relations needs to be created or already exist
+ * (in any case, they will be freed by this function).
+ */
+void BKE_lib_override_library_dependencies_tag(struct Main *bmain,
+ struct ID *id_root,
+ const uint tag,
+ const bool do_create_main_relashionships)
+{
+ id_root->tag |= tag;
+
+ if (do_create_main_relashionships) {
+ BKE_main_relations_create(bmain, 0);
+ }
+
+ /* Then we tag all intermediary data-blocks in-between two overridden ones (e.g. if a shapekey
+ * has a driver using an armature object's bone, we need to override the shapekey/obdata, the
+ * objects using them, etc.) */
+ lib_override_hierarchy_recursive_tag(bmain, id_root);
+
+ BKE_main_relations_free(bmain);
+}
+
/* We only build override GHash on request. */
BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_mapping_ensure(
IDOverrideLibrary *override)
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 49c909850de..7e859799a4e 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -624,7 +624,7 @@ void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float
co, bezt->vec[1], bezt->vec[2], bezt_next->vec[0], bezt_next->vec[1], u);
}
-BLI_INLINE void orthogonal_direction_get(float vec[2], float result[2])
+BLI_INLINE void orthogonal_direction_get(const float vec[2], float result[2])
{
result[0] = -vec[1];
result[1] = vec[0];
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 412ccd3ab39..7f98266becc 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -1256,7 +1256,7 @@ static float maskrasterize_layer_z_depth_quad(
return w[2] + w[3]; /* we can make this assumption for small speedup */
}
-static float maskrasterize_layer_isect(unsigned int *face,
+static float maskrasterize_layer_isect(const unsigned int *face,
float (*cos)[3],
const float dist_orig,
const float xy[2])
@@ -1489,6 +1489,8 @@ static void maskrasterize_buffer_cb(void *__restrict userdata,
void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle,
const unsigned int width,
const unsigned int height,
+ /* Cannot be const, because it is assigned to non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
float *buffer)
{
const float x_inv = 1.0f / (float)width;
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index b298a6a2787..49957b584ad 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -2888,7 +2888,7 @@ void BKE_mesh_loops_to_mface_corners(
void BKE_mesh_loops_to_tessdata(CustomData *fdata,
CustomData *ldata,
MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces)
{
@@ -2981,7 +2981,7 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata,
void BKE_mesh_tangent_loops_to_tessdata(CustomData *fdata,
CustomData *ldata,
MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces,
const char *layer_name)
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 4ed9b31dbb5..686f58a0ceb 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -953,7 +953,7 @@ void BKE_mesh_loop_islands_free(MeshIslandStore *island_store)
void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
const int item_num,
- int *items_indices,
+ const int *items_indices,
const int num_island_items,
int *island_item_indices,
const int num_innercut_items,
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index 404d6a581ae..a4991675d2d 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -1071,7 +1071,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
BLI_bitmap *done_edges,
MeshElemMap *edge_to_poly_map,
const bool is_edge_innercut,
- int *poly_island_index_map,
+ const int *poly_island_index_map,
float (*poly_centers)[3],
unsigned char *poly_status)
{
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 7e78be6d66e..71d49dd1c19 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -175,7 +175,7 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden,
return subd;
}
-static BLI_bitmap *multires_mdisps_downsample_hidden(BLI_bitmap *old_hidden,
+static BLI_bitmap *multires_mdisps_downsample_hidden(const BLI_bitmap *old_hidden,
int old_level,
int new_level)
{
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c
index 6bd7b6b6a98..fa1a53f946e 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.c
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.c
@@ -80,7 +80,7 @@
/**
* Used to check if a vertex is in a disconnected element ID.
*/
-static bool is_vertex_in_id(BMVert *v, int *elem_id, int elem)
+static bool is_vertex_in_id(BMVert *v, const int *elem_id, int elem)
{
const int v_index = BM_elem_index_get(v);
return elem_id[v_index] == elem;
diff --git a/source/blender/blenkernel/intern/node_tree_multi_function.cc b/source/blender/blenkernel/intern/node_tree_multi_function.cc
index 02437d98732..4e505db9b9d 100644
--- a/source/blender/blenkernel/intern/node_tree_multi_function.cc
+++ b/source/blender/blenkernel/intern/node_tree_multi_function.cc
@@ -16,6 +16,8 @@
#include "BKE_node_tree_multi_function.hh"
+#include "BLI_float3.hh"
+
namespace blender {
namespace bke {
@@ -136,11 +138,72 @@ static fn::MFOutputSocket *try_find_origin(CommonMFNetworkBuilderData &common,
}
if (from_dsockets.size() == 1) {
- return &common.network_map.lookup(*from_dsockets[0]);
+ if (is_multi_function_data_socket(from_dsockets[0]->bsocket())) {
+ return &common.network_map.lookup(*from_dsockets[0]);
+ }
+ else {
+ return nullptr;
+ }
+ }
+ else {
+ if (is_multi_function_data_socket(from_group_inputs[0]->bsocket())) {
+ return &common.network_map.lookup(*from_group_inputs[0]);
+ }
+ else {
+ return nullptr;
+ }
+ }
+}
+
+static const fn::MultiFunction *try_get_conversion_function(fn::MFDataType from, fn::MFDataType to)
+{
+ if (from == fn::MFDataType::ForSingle<float>()) {
+ if (to == fn::MFDataType::ForSingle<int32_t>()) {
+ static fn::CustomMF_Convert<float, int32_t> function;
+ return &function;
+ }
+ if (to == fn::MFDataType::ForSingle<float3>()) {
+ static fn::CustomMF_Convert<float, float3> function;
+ return &function;
+ }
+ }
+ if (from == fn::MFDataType::ForSingle<float3>()) {
+ if (to == fn::MFDataType::ForSingle<float>()) {
+ static fn::CustomMF_SI_SO<float3, float> function{"Vector Length",
+ [](float3 a) { return a.length(); }};
+ return &function;
+ }
+ }
+ if (from == fn::MFDataType::ForSingle<int32_t>()) {
+ if (to == fn::MFDataType::ForSingle<float>()) {
+ static fn::CustomMF_Convert<int32_t, float> function;
+ return &function;
+ }
+ if (to == fn::MFDataType::ForSingle<float3>()) {
+ static fn::CustomMF_SI_SO<int32_t, float3> function{
+ "int32 to float3", [](int32_t a) { return float3((float)a); }};
+ return &function;
+ }
+ }
+
+ return nullptr;
+}
+
+static fn::MFOutputSocket &insert_default_value_for_type(CommonMFNetworkBuilderData &common,
+ fn::MFDataType type)
+{
+ const fn::MultiFunction *default_fn;
+ if (type.is_single()) {
+ default_fn = &common.resources.construct<fn::CustomMF_GenericConstant>(
+ AT, type.single_type(), type.single_type().default_value());
}
else {
- return &common.network_map.lookup(*from_group_inputs[0]);
+ default_fn = &common.resources.construct<fn::CustomMF_GenericConstantArray>(
+ AT, fn::GSpan(type.vector_base_type()));
}
+
+ fn::MFNode &node = common.network.add_function(*default_fn);
+ return node.output(0);
}
static void insert_links(CommonMFNetworkBuilderData &common)
@@ -149,24 +212,34 @@ static void insert_links(CommonMFNetworkBuilderData &common)
if (!to_dsocket->is_available()) {
continue;
}
-
- if (!is_multi_function_data_socket(to_dsocket->bsocket())) {
+ if (!to_dsocket->is_linked()) {
continue;
}
-
- fn::MFOutputSocket *from_socket = try_find_origin(common, *to_dsocket);
- if (from_socket == nullptr) {
+ if (!is_multi_function_data_socket(to_dsocket->bsocket())) {
continue;
}
Span<fn::MFInputSocket *> to_sockets = common.network_map.lookup(*to_dsocket);
BLI_assert(to_sockets.size() >= 1);
+ fn::MFDataType to_type = to_sockets[0]->data_type();
+
+ fn::MFOutputSocket *from_socket = try_find_origin(common, *to_dsocket);
+ if (from_socket == nullptr) {
+ from_socket = &insert_default_value_for_type(common, to_type);
+ }
fn::MFDataType from_type = from_socket->data_type();
- fn::MFDataType to_type = to_sockets[0]->data_type();
if (from_type != to_type) {
- /* Todo: Try inserting implicit conversion. */
+ const fn::MultiFunction *conversion_fn = try_get_conversion_function(from_type, to_type);
+ if (conversion_fn != nullptr) {
+ fn::MFNode &node = common.network.add_function(*conversion_fn);
+ common.network.add_link(*from_socket, node.input(0));
+ from_socket = &node.output(0);
+ }
+ else {
+ from_socket = &insert_default_value_for_type(common, to_type);
+ }
}
for (fn::MFInputSocket *to_socket : to_sockets) {
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index 6ca1442497a..51ec89cf77d 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -68,7 +68,7 @@ static Lattice *object_defgroup_lattice_get(ID *id)
*
* \param map: an array mapping old indices to new indices.
*/
-void BKE_object_defgroup_remap_update_users(Object *ob, int *map)
+void BKE_object_defgroup_remap_update_users(Object *ob, const int *map)
{
ModifierData *md;
ParticleSystem *psys;
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 609c5c1e580..f94ef946851 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -147,19 +147,19 @@ static void init_complex(fftw_complex cmpl, float real, float image)
cmpl[1] = image;
}
-static void add_comlex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl2)
+static void add_comlex_c(fftw_complex res, const fftw_complex cmpl1, const fftw_complex cmpl2)
{
res[0] = cmpl1[0] + cmpl2[0];
res[1] = cmpl1[1] + cmpl2[1];
}
-static void mul_complex_f(fftw_complex res, fftw_complex cmpl, float f)
+static void mul_complex_f(fftw_complex res, const fftw_complex cmpl, float f)
{
res[0] = cmpl[0] * (double)f;
res[1] = cmpl[1] * (double)f;
}
-static void mul_complex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl2)
+static void mul_complex_c(fftw_complex res, const fftw_complex cmpl1, const fftw_complex cmpl2)
{
fftwf_complex temp;
temp[0] = cmpl1[0] * cmpl2[0] - cmpl1[1] * cmpl2[1];
@@ -178,7 +178,7 @@ static float image_c(fftw_complex cmpl)
return cmpl[1];
}
-static void conj_complex(fftw_complex res, fftw_complex cmpl1)
+static void conj_complex(fftw_complex res, const fftw_complex cmpl1)
{
res[0] = cmpl1[0];
res[1] = -cmpl1[1];
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index 7b9b2484dbe..e0dccd4d14a 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -433,7 +433,7 @@ static void psys_uv_to_w(float u, float v, int quad, float *w)
}
/* Find the index in "sum" array before "value" is crossed. */
-static int distribute_binary_search(float *sum, int n, float value)
+static int distribute_binary_search(const float *sum, int n, float value)
{
int mid, low = 0, high = n - 1;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index cd821077292..bf9aea81181 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -4966,6 +4966,7 @@ void particle_system_update(struct Depsgraph *depsgraph,
psys_orig->flag = (psys->flag & ~PSYS_SHARED_CACHES);
psys_orig->cfra = psys->cfra;
psys_orig->recalc = psys->recalc;
+ psys_orig->part->totpart = part->totpart;
}
}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 870a1f3d673..67988427bd2 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -358,7 +358,7 @@ static void update_vb(PBVH *pbvh, PBVHNode *node, BBC *prim_bbc, int offset, int
/* Returns the number of visible quads in the nodes' grids. */
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
- int *grid_indices,
+ const int *grid_indices,
int totgrid,
int gridsize)
{
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index ce5402551b6..9a9d8dc215b 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -206,7 +206,7 @@ static int ptcache_softbody_write(int index, void *soft_v, void **data, int UNUS
return 1;
}
static void ptcache_softbody_read(
- int index, void *soft_v, void **data, float UNUSED(cfra), float *old_data)
+ int index, void *soft_v, void **data, float UNUSED(cfra), const float *old_data)
{
SoftBody *soft = soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -220,8 +220,13 @@ static void ptcache_softbody_read(
PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, bp->vec);
}
}
-static void ptcache_softbody_interpolate(
- int index, void *soft_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_softbody_interpolate(int index,
+ void *soft_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
SoftBody *soft = soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -316,7 +321,7 @@ static int ptcache_particle_write(int index, void *psys_v, void **data, int cfra
return 1 + (pa->state.time >= pa->time && pa->prev_state.time <= pa->time);
}
static void ptcache_particle_read(
- int index, void *psys_v, void **data, float cfra, float *old_data)
+ int index, void *psys_v, void **data, float cfra, const float *old_data)
{
ParticleSystem *psys = psys_v;
ParticleData *pa;
@@ -383,8 +388,13 @@ static void ptcache_particle_read(
unit_qt(pa->state.rot);
}
}
-static void ptcache_particle_interpolate(
- int index, void *psys_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_particle_interpolate(int index,
+ void *psys_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
ParticleSystem *psys = psys_v;
ParticleData *pa;
@@ -528,7 +538,7 @@ static int ptcache_cloth_write(int index, void *cloth_v, void **data, int UNUSED
return 1;
}
static void ptcache_cloth_read(
- int index, void *cloth_v, void **data, float UNUSED(cfra), float *old_data)
+ int index, void *cloth_v, void **data, float UNUSED(cfra), const float *old_data)
{
ClothModifierData *clmd = cloth_v;
Cloth *cloth = clmd->clothObject;
@@ -545,8 +555,13 @@ static void ptcache_cloth_read(
PTCACHE_DATA_TO(data, BPHYS_DATA_XCONST, 0, vert->xconst);
}
}
-static void ptcache_cloth_interpolate(
- int index, void *cloth_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_cloth_interpolate(int index,
+ void *cloth_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
ClothModifierData *clmd = cloth_v;
Cloth *cloth = clmd->clothObject;
@@ -1509,7 +1524,7 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUSE
return 1;
}
static void ptcache_rigidbody_read(
- int index, void *rb_v, void **data, float UNUSED(cfra), float *old_data)
+ int index, void *rb_v, void **data, float UNUSED(cfra), const float *old_data)
{
RigidBodyWorld *rbw = rb_v;
Object *ob = NULL;
@@ -1534,8 +1549,13 @@ static void ptcache_rigidbody_read(
}
}
}
-static void ptcache_rigidbody_interpolate(
- int index, void *rb_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_rigidbody_interpolate(int index,
+ void *rb_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
RigidBodyWorld *rbw = rb_v;
Object *ob = NULL;
@@ -1887,7 +1907,7 @@ static int ptcache_sim_particle_write(int index, void *state_v, void **data, int
return 1;
}
static void ptcache_sim_particle_read(
- int index, void *state_v, void **data, float UNUSED(cfra), float *UNUSED(old_data))
+ int index, void *state_v, void **data, float UNUSED(cfra), const float *UNUSED(old_data))
{
ParticleSimulationState *state = (ParticleSimulationState *)state_v;
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index de233a8d473..4a2ad88bb28 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2668,7 +2668,7 @@ static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int heig
}
static void RVIsolateHighlights_float(
- float *in, float *out, int width, int height, float threshold, float boost, float clamp)
+ const float *in, float *out, int width, int height, float threshold, float boost, float clamp)
{
int x, y, index;
float intensity;
@@ -3423,7 +3423,7 @@ static void do_gaussian_blur_effect_byte_x(Sequence *seq,
int y,
int frame_width,
int UNUSED(frame_height),
- unsigned char *rect,
+ const unsigned char *rect,
unsigned char *out)
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
@@ -3473,7 +3473,7 @@ static void do_gaussian_blur_effect_byte_y(Sequence *seq,
int y,
int UNUSED(frame_width),
int frame_height,
- unsigned char *rect,
+ const unsigned char *rect,
unsigned char *out)
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 604cbf476a8..a630170d6d5 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -57,7 +57,7 @@ typedef void (*modifier_apply_threaded_cb)(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v);
typedef struct ModifierInitData {
@@ -223,7 +223,7 @@ static void whiteBalance_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
int x, y;
@@ -331,7 +331,7 @@ static void curves_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *)data_v;
@@ -461,7 +461,7 @@ static void hue_correct_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *)data_v;
@@ -556,7 +556,7 @@ static void brightcontrast_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
BrightContrastThreadData *data = (BrightContrastThreadData *)data_v;
@@ -658,7 +658,7 @@ static void maskmodifier_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *UNUSED(data_v))
{
int x, y;
@@ -755,7 +755,7 @@ static void tonemapmodifier_apply_threaded_simple(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
AvgLogLum *avg = (AvgLogLum *)data_v;
@@ -814,7 +814,7 @@ static void tonemapmodifier_apply_threaded_photoreceptor(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
AvgLogLum *avg = (AvgLogLum *)data_v;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 01d2176ba30..7339c887151 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1090,6 +1090,64 @@ void BKE_sequence_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, cons
BKE_sequence_calc(scene, seq);
}
+void BKE_sequence_movie_reload_if_needed(struct Main *bmain,
+ struct Scene *scene,
+ struct Sequence *seq,
+ bool *r_was_reloaded,
+ bool *r_can_produce_frames)
+{
+ BLI_assert(seq->type == SEQ_TYPE_MOVIE ||
+ !"This function is only implemented for movie strips.");
+
+ bool must_reload = false;
+
+ /* The Sequence struct allows for multiple anim structs to be associated with one strip. This
+ * function will return true only if there is at least one 'anim' AND all anims can produce
+ * frames. */
+
+ if (BLI_listbase_is_empty(&seq->anims)) {
+ /* No anim present, so reloading is always necessary. */
+ must_reload = true;
+ }
+ else {
+ LISTBASE_FOREACH (StripAnim *, sanim, &seq->anims) {
+ if (!IMB_anim_can_produce_frames(sanim->anim)) {
+ /* Anim cannot produce frames, try reloading. */
+ must_reload = true;
+ break;
+ }
+ };
+ }
+
+ if (!must_reload) {
+ /* There are one or more anims, and all can produce frames. */
+ *r_was_reloaded = false;
+ *r_can_produce_frames = true;
+ return;
+ }
+
+ BKE_sequence_reload_new_file(bmain, scene, seq, true);
+ *r_was_reloaded = true;
+
+ if (BLI_listbase_is_empty(&seq->anims)) {
+ /* No anims present after reloading => no frames can be produced. */
+ *r_can_produce_frames = false;
+ return;
+ }
+
+ /* Check if there are still anims that cannot produce frames. */
+ LISTBASE_FOREACH (StripAnim *, sanim, &seq->anims) {
+ if (!IMB_anim_can_produce_frames(sanim->anim)) {
+ /* There still is an anim that cannot produce frames. */
+ *r_can_produce_frames = false;
+ return;
+ }
+ };
+
+ /* There are one or more anims, and all can produce frames. */
+ *r_can_produce_frames = true;
+}
+
void BKE_sequencer_sort(Scene *scene)
{
/* all strips together per kind, and in order of y location ("machine") */
@@ -2390,7 +2448,7 @@ static void color_balance_byte_float(StripColorBalance *cb_,
static void color_balance_float_float(StripColorBalance *cb_,
float *rect_float,
- float *mask_rect_float,
+ const float *mask_rect_float,
int width,
int height,
float mul)
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index 35ef664dce3..e163bb8da8d 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -176,6 +176,10 @@ static void ensure_attributes_exist(ParticleSimulationState *state)
CustomData_add_layer_named(
&state->attributes, CD_LOCATION, CD_CALLOC, nullptr, state->tot_particles, "Velocity");
}
+ if (CustomData_get_layer_named(&state->attributes, CD_PROP_INT32, "ID") == nullptr) {
+ CustomData_add_layer_named(
+ &state->attributes, CD_PROP_INT32, CD_CALLOC, nullptr, state->tot_particles, "ID");
+ }
}
static void copy_states_to_cow(Simulation *simulation_orig, Simulation *simulation_cow)
@@ -211,11 +215,8 @@ static void copy_states_to_cow(Simulation *simulation_orig, Simulation *simulati
}
}
-using AttributeNodeMap = Map<fn::MFDummyNode *, std::pair<std::string, fn::MFDataType>>;
-
-static AttributeNodeMap deduplicate_attribute_nodes(fn::MFNetwork &network,
- MFNetworkTreeMap &network_map,
- const DerivedNodeTree &tree)
+static Map<const fn::MFOutputSocket *, std::string> deduplicate_attribute_nodes(
+ fn::MFNetwork &network, MFNetworkTreeMap &network_map, const DerivedNodeTree &tree)
{
Span<const DNode *> attribute_dnodes = tree.nodes_by_type("SimulationNodeParticleAttribute");
uint amount = attribute_dnodes.size();
@@ -247,11 +248,11 @@ static AttributeNodeMap deduplicate_attribute_nodes(fn::MFNetwork &network,
attribute_nodes_by_name_and_type;
for (uint i : IndexRange(amount)) {
attribute_nodes_by_name_and_type
- .lookup_or_add_default({attribute_names[i], name_sockets[i]->data_type()})
+ .lookup_or_add_default({attribute_names[i], name_sockets[i]->node().output(0).data_type()})
.append(&name_sockets[i]->node());
}
- AttributeNodeMap final_attribute_nodes;
+ Map<const fn::MFOutputSocket *, std::string> attribute_inputs;
for (auto item : attribute_nodes_by_name_and_type.items()) {
StringRef attribute_name = item.key.first;
fn::MFDataType data_type = item.key.second;
@@ -264,10 +265,10 @@ static AttributeNodeMap deduplicate_attribute_nodes(fn::MFNetwork &network,
}
network.remove(nodes);
- final_attribute_nodes.add_new(&new_attribute_socket.node().as_dummy(), item.key);
+ attribute_inputs.add_new(&new_attribute_socket, attribute_name);
}
- return final_attribute_nodes;
+ return attribute_inputs;
}
class CustomDataAttributesRef {
@@ -282,7 +283,16 @@ class CustomDataAttributesRef {
fn::AttributesInfoBuilder builder;
for (const CustomDataLayer &layer : Span(custom_data.layers, custom_data.totlayer)) {
buffers_.append(layer.data);
- builder.add<float3>(layer.name, {0, 0, 0});
+ switch (layer.type) {
+ case CD_PROP_INT32: {
+ builder.add<int32_t>(layer.name, 0);
+ break;
+ }
+ case CD_LOCATION: {
+ builder.add<float3>(layer.name, {0, 0, 0});
+ break;
+ }
+ }
}
info_ = std::make_unique<fn::AttributesInfo>(builder);
size_ = size;
@@ -386,6 +396,322 @@ static void update_simulation_state_list(Simulation *simulation, const DerivedNo
add_missing_particle_states(simulation, state_names);
}
+class ParticleFunctionInput {
+ public:
+ virtual ~ParticleFunctionInput() = default;
+ virtual void add_input(fn::AttributesRef attributes,
+ fn::MFParamsBuilder &params,
+ ResourceCollector &resources) const = 0;
+};
+
+class ParticleFunction {
+ private:
+ const fn::MultiFunction *global_fn_;
+ const fn::MultiFunction *per_particle_fn_;
+ Array<const ParticleFunctionInput *> global_inputs_;
+ Array<const ParticleFunctionInput *> per_particle_inputs_;
+ Array<bool> output_is_global_;
+ Vector<uint> global_output_indices_;
+ Vector<uint> per_particle_output_indices_;
+ Vector<fn::MFDataType> output_types_;
+ Vector<StringRefNull> output_names_;
+
+ friend class ParticleFunctionEvaluator;
+
+ public:
+ ParticleFunction(const fn::MultiFunction *global_fn,
+ const fn::MultiFunction *per_particle_fn,
+ Span<const ParticleFunctionInput *> global_inputs,
+ Span<const ParticleFunctionInput *> per_particle_inputs,
+ Span<bool> output_is_global)
+ : global_fn_(global_fn),
+ per_particle_fn_(per_particle_fn),
+ global_inputs_(global_inputs),
+ per_particle_inputs_(per_particle_inputs),
+ output_is_global_(output_is_global)
+ {
+ for (uint i : output_is_global_.index_range()) {
+ if (output_is_global_[i]) {
+ uint param_index = global_inputs_.size() + global_output_indices_.size();
+ fn::MFParamType param_type = global_fn_->param_type(param_index);
+ BLI_assert(param_type.is_output());
+ output_types_.append(param_type.data_type());
+ output_names_.append(global_fn_->param_name(param_index));
+ global_output_indices_.append(i);
+ }
+ else {
+ uint param_index = per_particle_inputs_.size() + per_particle_output_indices_.size();
+ fn::MFParamType param_type = per_particle_fn_->param_type(param_index);
+ BLI_assert(param_type.is_output());
+ output_types_.append(param_type.data_type());
+ output_names_.append(per_particle_fn_->param_name(param_index));
+ per_particle_output_indices_.append(i);
+ }
+ }
+ }
+};
+
+class ParticleFunctionEvaluator {
+ private:
+ ResourceCollector resources_;
+ const ParticleFunction &particle_fn_;
+ IndexMask mask_;
+ fn::MFContextBuilder global_context_;
+ fn::MFContextBuilder per_particle_context_;
+ fn::AttributesRef particle_attributes_;
+ Vector<void *> outputs_;
+ bool is_computed_ = false;
+
+ public:
+ ParticleFunctionEvaluator(const ParticleFunction &particle_fn,
+ IndexMask mask,
+ fn::AttributesRef particle_attributes)
+ : particle_fn_(particle_fn),
+ mask_(mask),
+ particle_attributes_(particle_attributes),
+ outputs_(particle_fn_.output_types_.size(), nullptr)
+ {
+ }
+
+ ~ParticleFunctionEvaluator()
+ {
+ for (uint output_index : outputs_.index_range()) {
+ void *buffer = outputs_[output_index];
+ fn::MFDataType data_type = particle_fn_.output_types_[output_index];
+ BLI_assert(data_type.is_single()); /* For now. */
+ const fn::CPPType &type = data_type.single_type();
+
+ if (particle_fn_.output_is_global_[output_index]) {
+ type.destruct(buffer);
+ }
+ else {
+ type.destruct_indices(outputs_[0], mask_);
+ }
+ }
+ }
+
+ void compute()
+ {
+ BLI_assert(!is_computed_);
+ this->compute_globals();
+ this->compute_per_particle();
+ is_computed_ = true;
+ }
+
+ template<typename T> fn::VSpan<T> get(uint output_index, StringRef expected_name) const
+ {
+ return this->get(output_index, expected_name).typed<T>();
+ }
+
+ fn::GVSpan get(uint output_index, StringRef expected_name) const
+ {
+#ifdef DEBUG
+ StringRef real_name = particle_fn_.output_names_[output_index];
+ BLI_assert(expected_name == real_name);
+ BLI_assert(is_computed_);
+#endif
+ UNUSED_VARS_NDEBUG(expected_name);
+ const void *buffer = outputs_[output_index];
+ const fn::CPPType &type = particle_fn_.output_types_[output_index].single_type();
+ if (particle_fn_.output_is_global_[output_index]) {
+ return fn::GVSpan::FromSingleWithMaxSize(type, buffer);
+ }
+ else {
+ return fn::GVSpan(fn::GSpan(type, buffer, mask_.min_array_size()));
+ }
+ }
+
+ private:
+ void compute_globals()
+ {
+ if (particle_fn_.global_fn_ == nullptr) {
+ return;
+ }
+
+ fn::MFParamsBuilder params(*particle_fn_.global_fn_, mask_.min_array_size());
+
+ /* Add input parameters. */
+ for (const ParticleFunctionInput *input : particle_fn_.global_inputs_) {
+ input->add_input(particle_attributes_, params, resources_);
+ }
+
+ /* Add output parameters. */
+ for (uint output_index : particle_fn_.global_output_indices_) {
+ fn::MFDataType data_type = particle_fn_.output_types_[output_index];
+ BLI_assert(data_type.is_single()); /* For now. */
+
+ const fn::CPPType &type = data_type.single_type();
+ void *buffer = resources_.linear_allocator().allocate(type.size(), type.alignment());
+ params.add_uninitialized_single_output(fn::GMutableSpan(type, buffer, 1));
+ outputs_[output_index] = buffer;
+ }
+
+ particle_fn_.global_fn_->call({0}, params, global_context_);
+ }
+
+ void compute_per_particle()
+ {
+ if (particle_fn_.per_particle_fn_ == nullptr) {
+ return;
+ }
+
+ fn::MFParamsBuilder params(*particle_fn_.per_particle_fn_, mask_.min_array_size());
+
+ /* Add input parameters. */
+ for (const ParticleFunctionInput *input : particle_fn_.per_particle_inputs_) {
+ input->add_input(particle_attributes_, params, resources_);
+ }
+
+ /* Add output parameters. */
+ for (uint output_index : particle_fn_.per_particle_output_indices_) {
+ fn::MFDataType data_type = particle_fn_.output_types_[output_index];
+ BLI_assert(data_type.is_single()); /* For now. */
+
+ const fn::CPPType &type = data_type.single_type();
+ void *buffer = resources_.linear_allocator().allocate(type.size() * mask_.min_array_size(),
+ type.alignment());
+ params.add_uninitialized_single_output(
+ fn::GMutableSpan(type, buffer, mask_.min_array_size()));
+ outputs_[output_index] = buffer;
+ }
+
+ particle_fn_.per_particle_fn_->call(mask_, params, global_context_);
+ }
+};
+
+class ParticleAttributeInput : public ParticleFunctionInput {
+ private:
+ std::string attribute_name_;
+ const fn::CPPType &attribute_type_;
+
+ public:
+ ParticleAttributeInput(std::string attribute_name, const fn::CPPType &attribute_type)
+ : attribute_name_(std::move(attribute_name)), attribute_type_(attribute_type)
+ {
+ }
+
+ void add_input(fn::AttributesRef attributes,
+ fn::MFParamsBuilder &params,
+ ResourceCollector &UNUSED(resources)) const override
+ {
+ std::optional<fn::GSpan> span = attributes.try_get(attribute_name_, attribute_type_);
+ if (span.has_value()) {
+ params.add_readonly_single_input(*span);
+ }
+ else {
+ params.add_readonly_single_input(fn::GVSpan::FromDefault(attribute_type_));
+ }
+ }
+};
+
+static const ParticleFunction *create_particle_function_for_inputs(
+ Span<const fn::MFInputSocket *> sockets_to_compute,
+ ResourceCollector &resources,
+ const Map<const fn::MFOutputSocket *, std::string> &attribute_inputs)
+{
+ BLI_assert(sockets_to_compute.size() >= 1);
+ const fn::MFNetwork &network = sockets_to_compute[0]->node().network();
+
+ VectorSet<const fn::MFOutputSocket *> dummy_deps;
+ VectorSet<const fn::MFInputSocket *> unlinked_input_deps;
+ network.find_dependencies(sockets_to_compute, dummy_deps, unlinked_input_deps);
+ BLI_assert(unlinked_input_deps.size() == 0);
+
+ Vector<const ParticleFunctionInput *> per_particle_inputs;
+ for (const fn::MFOutputSocket *socket : dummy_deps) {
+ StringRef attribute_name = attribute_inputs.lookup(socket);
+ per_particle_inputs.append(&resources.construct<ParticleAttributeInput>(
+ AT, attribute_name, socket->data_type().single_type()));
+ }
+
+ const fn::MultiFunction &per_particle_fn = resources.construct<fn::MFNetworkEvaluator>(
+ AT, dummy_deps.as_span(), sockets_to_compute);
+
+ Array<bool> output_is_global(sockets_to_compute.size(), false);
+
+ const ParticleFunction &particle_fn = resources.construct<ParticleFunction>(
+ AT,
+ nullptr,
+ &per_particle_fn,
+ Span<const ParticleFunctionInput *>(),
+ per_particle_inputs.as_span(),
+ output_is_global.as_span());
+
+ return &particle_fn;
+}
+
+class ParticleForce {
+ public:
+ virtual ~ParticleForce() = default;
+ virtual void add_force(fn::AttributesRef attributes,
+ MutableSpan<float3> r_combined_force) const = 0;
+};
+
+class ParticleFunctionForce : public ParticleForce {
+ private:
+ const ParticleFunction &particle_fn_;
+
+ public:
+ ParticleFunctionForce(const ParticleFunction &particle_fn) : particle_fn_(particle_fn)
+ {
+ }
+
+ void add_force(fn::AttributesRef attributes, MutableSpan<float3> r_combined_force) const override
+ {
+ IndexMask mask = IndexRange(attributes.size());
+ ParticleFunctionEvaluator evaluator{particle_fn_, mask, attributes};
+ evaluator.compute();
+ fn::VSpan<float3> forces = evaluator.get<float3>(0, "Force");
+ for (uint i : mask) {
+ r_combined_force[i] += forces[i];
+ }
+ }
+};
+
+static Vector<const ParticleForce *> create_forces_for_particle_simulation(
+ const DNode &simulation_node,
+ MFNetworkTreeMap &network_map,
+ ResourceCollector &resources,
+ const Map<const fn::MFOutputSocket *, std::string> &attribute_inputs)
+{
+ Vector<const ParticleForce *> forces;
+ for (const DOutputSocket *origin_socket : simulation_node.input(2, "Forces").linked_sockets()) {
+ const DNode &origin_node = origin_socket->node();
+ if (origin_node.idname() != "SimulationNodeForce") {
+ continue;
+ }
+
+ const fn::MFInputSocket &force_socket = network_map.lookup_dummy(
+ origin_node.input(0, "Force"));
+
+ const ParticleFunction *particle_fn = create_particle_function_for_inputs(
+ {&force_socket}, resources, attribute_inputs);
+
+ if (particle_fn == nullptr) {
+ continue;
+ }
+
+ const ParticleForce &force = resources.construct<ParticleFunctionForce>(AT, *particle_fn);
+ forces.append(&force);
+ }
+ return forces;
+}
+
+static Map<std::string, Vector<const ParticleForce *>> collect_forces(
+ MFNetworkTreeMap &network_map,
+ ResourceCollector &resources,
+ const Map<const fn::MFOutputSocket *, std::string> &attribute_inputs)
+{
+ Map<std::string, Vector<const ParticleForce *>> forces_by_simulation;
+ for (const DNode *dnode : network_map.tree().nodes_by_type("SimulationNodeParticleSimulation")) {
+ std::string name = dnode_to_path(*dnode);
+ Vector<const ParticleForce *> forces = create_forces_for_particle_simulation(
+ *dnode, network_map, resources, attribute_inputs);
+ forces_by_simulation.add_new(std::move(name), std::move(forces));
+ }
+ return forces_by_simulation;
+}
+
static void simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation_cow)
{
int current_frame = scene->r.cfra;
@@ -406,12 +732,15 @@ static void simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulatio
fn::MFNetwork network;
ResourceCollector resources;
MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources);
- AttributeNodeMap attribute_node_map = deduplicate_attribute_nodes(network, network_map, tree);
+ // WM_clipboard_text_set(tree.to_dot().c_str(), false);
+ Map<const fn::MFOutputSocket *, std::string> attribute_inputs = deduplicate_attribute_nodes(
+ network, network_map, tree);
fn::mf_network_optimization::constant_folding(network, resources);
fn::mf_network_optimization::common_subnetwork_elimination(network);
fn::mf_network_optimization::dead_node_removal(network);
- UNUSED_VARS(attribute_node_map);
- // WM_clipboard_text_set(network.to_dot().c_str(), false);
+
+ Map<std::string, Vector<const ParticleForce *>> forces_by_simulation = collect_forces(
+ network_map, resources, attribute_inputs);
if (current_frame == 1) {
reinitialize_empty_simulation_states(simulation_orig, tree);
@@ -420,7 +749,7 @@ static void simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulatio
simulation_orig->current_frame = 1;
LISTBASE_FOREACH (ParticleSimulationState *, state, &simulation_orig->states) {
- state->tot_particles = 100;
+ state->tot_particles = 1000;
CustomData_realloc(&state->attributes, state->tot_particles);
ensure_attributes_exist(state);
@@ -430,10 +759,12 @@ static void simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulatio
fn::MutableAttributesRef attributes = custom_data_attributes;
MutableSpan<float3> positions = attributes.get<float3>("Position");
MutableSpan<float3> velocities = attributes.get<float3>("Velocity");
+ MutableSpan<int32_t> ids = attributes.get<int32_t>("ID");
for (uint i : positions.index_range()) {
- positions[i] = {i / 10.0f, 0, 0};
+ positions[i] = {i / 100.0f, 0, 0};
velocities[i] = {0, BLI_rng_get_float(rng), BLI_rng_get_float(rng) * 2 + 1};
+ ids[i] = i;
}
}
@@ -456,8 +787,14 @@ static void simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulatio
MutableSpan<float3> positions = attributes.get<float3>("Position");
MutableSpan<float3> velocities = attributes.get<float3>("Velocity");
+ Array<float3> force_vectors{(uint)state->tot_particles, {0, 0, 0}};
+ Span<const ParticleForce *> forces = forces_by_simulation.lookup_as(state->head.name);
+ for (const ParticleForce *force : forces) {
+ force->add_force(attributes, force_vectors);
+ }
+
for (uint i : positions.index_range()) {
- velocities[i].z += -1.0f * time_step;
+ velocities[i] += force_vectors[i] * time_step;
positions[i] += velocities[i] * time_step;
}
}
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index e155dedeef0..0809e8dda6d 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -507,9 +507,7 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack,
/* Might not be final place for this to be called - probably only want to call it from some
* undo handlers, not all of them? */
- if (BKE_lib_override_library_is_enabled()) {
- BKE_lib_override_library_main_operations_create(G_MAIN, false);
- }
+ BKE_lib_override_library_main_operations_create(G_MAIN, false);
/* Remove all undos after (also when 'ustack->step_active == NULL'). */
while (ustack->steps.last != ustack->step_active) {