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/pointcache.c')
-rw-r--r--source/blender/blenkernel/intern/pointcache.c164
1 files changed, 148 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 7c8527a8702..5c60b39e9c8 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -44,6 +44,7 @@
#include "DNA_simulation_types.h"
#include "BLI_blenlib.h"
+#include "BLI_endian_switch.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -67,6 +68,8 @@
#include "BKE_scene.h"
#include "BKE_softbody.h"
+#include "BLO_read_write.h"
+
#include "BIK_api.h"
#ifdef WITH_BULLET
@@ -256,7 +259,9 @@ static int ptcache_softbody_totpoint(void *soft_v, int UNUSED(cfra))
SoftBody *soft = soft_v;
return soft->totpoint;
}
-static void ptcache_softbody_error(void *UNUSED(soft_v), const char *UNUSED(message))
+static void ptcache_softbody_error(const ID *UNUSED(owner_id),
+ void *UNUSED(soft_v),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -460,7 +465,7 @@ static void ptcache_particle_interpolate(int index,
psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
interp_qt_qtqt(pa->state.rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra);
- mul_v3_fl(pa->state.vel, 1.f / (dfra * timestep));
+ mul_v3_fl(pa->state.vel, 1.0f / (dfra * timestep));
pa->state.time = cfra;
}
@@ -471,7 +476,9 @@ static int ptcache_particle_totpoint(void *psys_v, int UNUSED(cfra))
return psys->totpart;
}
-static void ptcache_particle_error(void *UNUSED(psys_v), const char *UNUSED(message))
+static void ptcache_particle_error(const ID *UNUSED(owner_id),
+ void *UNUSED(psys_v),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -642,10 +649,11 @@ static int ptcache_cloth_totpoint(void *cloth_v, int UNUSED(cfra))
return clmd->clothObject ? clmd->clothObject->mvert_num : 0;
}
-static void ptcache_cloth_error(void *cloth_v, const char *message)
+static void ptcache_cloth_error(const ID *owner_id, void *cloth_v, const char *message)
{
ClothModifierData *clmd = cloth_v;
- BKE_modifier_set_error(&clmd->modifier, "%s", message);
+ BLI_assert(GS(owner_id->name) == ID_OB);
+ BKE_modifier_set_error((Object *)owner_id, &clmd->modifier, "%s", message);
}
static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra))
@@ -659,7 +667,9 @@ static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra))
return surface->data->total_points;
}
-static void ptcache_dynamicpaint_error(void *UNUSED(sd), const char *UNUSED(message))
+static void ptcache_dynamicpaint_error(const ID *UNUSED(owner_id),
+ void *UNUSED(sd),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -731,8 +741,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
data_len = sizeof(PaintPoint);
}
- else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
- surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
+ else if (ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WEIGHT)) {
data_len = sizeof(float);
}
else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
@@ -853,7 +862,9 @@ static int ptcache_rigidbody_totpoint(void *rb_v, int UNUSED(cfra))
return rbw->numbodies;
}
-static void ptcache_rigidbody_error(void *UNUSED(rb_v), const char *UNUSED(message))
+static void ptcache_rigidbody_error(const struct ID *UNUSED(owner_id),
+ void *UNUSED(rb_v),
+ const char *UNUSED(message))
{
/* ignored for now */
}
@@ -2098,19 +2109,19 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra)
}
if (!ptcache_file_header_begin_read(pf)) {
- pid->error(pid->calldata, "Failed to read point cache file");
+ pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file");
error = 1;
}
else if (pf->type != pid->type) {
- pid->error(pid->calldata, "Point cache file has wrong type");
+ pid->error(pid->owner_id, pid->calldata, "Point cache file has wrong type");
error = 1;
}
else if (!pid->read_header(pf)) {
- pid->error(pid->calldata, "Failed to read point cache file header");
+ pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file header");
error = 1;
}
else if (pf->totpoint != pid->totpoint(pid->calldata, cfra)) {
- pid->error(pid->calldata, "Number of points in cache does not match mesh");
+ pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
error = 1;
}
@@ -2119,7 +2130,7 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra)
/* We have stream reading here. */
if (!pid->read_stream(pf, pid->calldata)) {
- pid->error(pid->calldata, "Failed to read point cache file data");
+ pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file data");
error = 1;
}
}
@@ -2155,7 +2166,7 @@ static int ptcache_read(PTCacheID *pid, int cfra)
int pid_totpoint = pid->totpoint(pid->calldata, cfra);
if (totpoint != pid_totpoint) {
- pid->error(pid->calldata, "Number of points in cache does not match mesh");
+ pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
totpoint = MIN2(totpoint, pid_totpoint);
}
}
@@ -2211,7 +2222,7 @@ static int ptcache_interpolate(PTCacheID *pid, float cfra, int cfra1, int cfra2)
int pid_totpoint = pid->totpoint(pid->calldata, (int)cfra);
if (totpoint != pid_totpoint) {
- pid->error(pid->calldata, "Number of points in cache does not match mesh");
+ pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh");
totpoint = MIN2(totpoint, pid_totpoint);
}
}
@@ -3771,3 +3782,124 @@ void BKE_ptcache_invalidate(PointCache *cache)
cache->last_exact = MIN2(cache->startframe, 0);
}
}
+
+static const char *ptcache_data_struct[] = {
+ "", // BPHYS_DATA_INDEX
+ "", // BPHYS_DATA_LOCATION
+ "", // BPHYS_DATA_VELOCITY
+ "", // BPHYS_DATA_ROTATION
+ "", // BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
+ "", // BPHYS_DATA_SIZE:
+ "", // BPHYS_DATA_TIMES:
+ "BoidData", // case BPHYS_DATA_BOIDS:
+};
+static const char *ptcache_extra_struct[] = {
+ "",
+ "ParticleSpring",
+ "vec3f",
+};
+void BKE_ptcache_blend_write(BlendWriter *writer, ListBase *ptcaches)
+{
+ LISTBASE_FOREACH (PointCache *, cache, ptcaches) {
+ BLO_write_struct(writer, PointCache, cache);
+
+ if ((cache->flag & PTCACHE_DISK_CACHE) == 0) {
+ LISTBASE_FOREACH (PTCacheMem *, pm, &cache->mem_cache) {
+ BLO_write_struct(writer, PTCacheMem, pm);
+
+ for (int i = 0; i < BPHYS_TOT_DATA; i++) {
+ if (pm->data[i] && pm->data_types & (1 << i)) {
+ if (ptcache_data_struct[i][0] == '\0') {
+ BLO_write_raw(writer, MEM_allocN_len(pm->data[i]), pm->data[i]);
+ }
+ else {
+ BLO_write_struct_array_by_name(
+ writer, ptcache_data_struct[i], pm->totpoint, pm->data[i]);
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (PTCacheExtra *, extra, &pm->extradata) {
+ if (ptcache_extra_struct[extra->type][0] == '\0') {
+ continue;
+ }
+ BLO_write_struct(writer, PTCacheExtra, extra);
+ BLO_write_struct_array_by_name(
+ writer, ptcache_extra_struct[extra->type], extra->totdata, extra->data);
+ }
+ }
+ }
+ }
+}
+
+static void direct_link_pointcache_cb(BlendDataReader *reader, void *data)
+{
+ PTCacheMem *pm = data;
+ for (int i = 0; i < BPHYS_TOT_DATA; i++) {
+ BLO_read_data_address(reader, &pm->data[i]);
+
+ /* the cache saves non-struct data without DNA */
+ if (pm->data[i] && ptcache_data_struct[i][0] == '\0' &&
+ BLO_read_requires_endian_switch(reader)) {
+ /* data_size returns bytes. */
+ int tot = (BKE_ptcache_data_size(i) * pm->totpoint) / sizeof(int);
+
+ int *poin = pm->data[i];
+
+ BLI_endian_switch_int32_array(poin, tot);
+ }
+ }
+
+ BLO_read_list(reader, &pm->extradata);
+
+ LISTBASE_FOREACH (PTCacheExtra *, extra, &pm->extradata) {
+ BLO_read_data_address(reader, &extra->data);
+ }
+}
+
+static void direct_link_pointcache(BlendDataReader *reader, PointCache *cache)
+{
+ if ((cache->flag & PTCACHE_DISK_CACHE) == 0) {
+ BLO_read_list_cb(reader, &cache->mem_cache, direct_link_pointcache_cb);
+ }
+ else {
+ BLI_listbase_clear(&cache->mem_cache);
+ }
+
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe = 0;
+ cache->edit = NULL;
+ cache->free_edit = NULL;
+ cache->cached_frames = NULL;
+ cache->cached_frames_len = 0;
+}
+
+void BKE_ptcache_blend_read_data(BlendDataReader *reader,
+ ListBase *ptcaches,
+ PointCache **ocache,
+ int force_disk)
+{
+ if (ptcaches->first) {
+ BLO_read_list(reader, ptcaches);
+ LISTBASE_FOREACH (PointCache *, cache, ptcaches) {
+ direct_link_pointcache(reader, cache);
+ if (force_disk) {
+ cache->flag |= PTCACHE_DISK_CACHE;
+ cache->step = 1;
+ }
+ }
+
+ BLO_read_data_address(reader, ocache);
+ }
+ else if (*ocache) {
+ /* old "single" caches need to be linked too */
+ BLO_read_data_address(reader, ocache);
+ direct_link_pointcache(reader, *ocache);
+ if (force_disk) {
+ (*ocache)->flag |= PTCACHE_DISK_CACHE;
+ (*ocache)->step = 1;
+ }
+
+ ptcaches->first = ptcaches->last = *ocache;
+ }
+}