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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2011-01-02 21:34:32 +0300
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2011-01-02 21:34:32 +0300
commitddcb91fc213cb9d9f87558f88a4831cd4c8e2791 (patch)
treeb3a266754610fff89abadfc3971721f432f2001f /source/blender/blenkernel
parent3ead3c4ff3a438202a9838843ed4000b26de62a7 (diff)
parentfe44c6596d6de906f1534f139b980e6d0a205bac (diff)
Merged changes in the trunk up to revision 34010.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_action.h2
-rw-r--r--source/blender/blenkernel/BKE_animsys.h8
-rw-r--r--source/blender/blenkernel/BKE_blender.h4
-rw-r--r--source/blender/blenkernel/BKE_customdata.h1
-rw-r--r--source/blender/blenkernel/BKE_deform.h2
-rw-r--r--source/blender/blenkernel/BKE_main.h1
-rw-r--r--source/blender/blenkernel/BKE_multires.h8
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h29
-rw-r--r--source/blender/blenkernel/intern/action.c15
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c293
-rw-r--r--source/blender/blenkernel/intern/armature.c16
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/customdata.c334
-rw-r--r--source/blender/blenkernel/intern/deform.c2
-rw-r--r--source/blender/blenkernel/intern/fcurve.c2
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c6
-rw-r--r--source/blender/blenkernel/intern/font.c2
-rw-r--r--source/blender/blenkernel/intern/key.c2
-rw-r--r--source/blender/blenkernel/intern/mball.c2
-rw-r--r--source/blender/blenkernel/intern/multires.c253
-rw-r--r--source/blender/blenkernel/intern/node.c106
-rw-r--r--source/blender/blenkernel/intern/particle.c6
-rw-r--r--source/blender/blenkernel/intern/particle_system.c6
-rw-r--r--source/blender/blenkernel/intern/pointcache.c1375
-rw-r--r--source/blender/blenkernel/intern/sequencer.c2
-rw-r--r--source/blender/blenkernel/intern/smoke.c2
-rw-r--r--source/blender/blenkernel/intern/softbody.c2
-rw-r--r--source/blender/blenkernel/intern/text.c8
28 files changed, 1502 insertions, 989 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 4d3f000c863..1c75387ba5d 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -117,6 +117,8 @@ void action_groups_remove_channel(struct bAction *act, struct FCurve *fcu);
/* Find a group with the given name */
struct bActionGroup *action_groups_find_named(struct bAction *act, const char name[]);
+/* Clear all 'temp' flags on all groups */
+void action_groups_clear_tempflags(struct bAction *act);
/* Pose API ----------------- */
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 3952b6066d3..500210d2fcd 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -100,6 +100,14 @@ void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, co
/* Fix all the paths for the entire database... */
void BKE_all_animdata_fix_paths_rename(char *prefix, char *oldName, char *newName);
+/* -------------------------------------- */
+
+/* Move animation data from src to destination if it's paths are based on basepaths */
+void BKE_animdata_separate_by_basepath(struct ID *srcID, struct ID *dstID, struct ListBase *basepaths);
+
+/* Move F-Curves from src to destination if it's path is based on basepath */
+void action_move_fcurves_by_basepath(struct bAction *srcAct, struct bAction *dstAct, const char basepath[]);
+
/* ************************************* */
/* Batch AnimData API */
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index a97c5fd8d9e..886a11b126e 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -44,8 +44,8 @@ struct ReportList;
struct Scene;
struct Main;
-#define BLENDER_VERSION 255
-#define BLENDER_SUBVERSION 1
+#define BLENDER_VERSION 256
+#define BLENDER_SUBVERSION 0
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index fb079d44bb5..e9118323682 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -144,6 +144,7 @@ void CustomData_em_copy_data(const struct CustomData *source,
void CustomData_bmesh_copy_data(const struct CustomData *source,
struct CustomData *dest,void *src_block,
void **dest_block);
+void CustomData_em_validate_data(struct CustomData *data, void *block, int sub_elements);
/* frees data in a CustomData object
* return 1 on success, 0 on failure
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 39df877f67b..52051712ff0 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -52,7 +52,7 @@ void defgroup_unique_name(struct bDeformGroup *dg, struct Object *ob);
struct MDeformWeight *defvert_find_index(const struct MDeformVert *dv, const int defgroup);
struct MDeformWeight *defvert_verify_index(struct MDeformVert *dv, const int defgroup);
-float defvert_find_weight(const struct MDeformVert *dvert, int group_num);
+float defvert_find_weight(const struct MDeformVert *dvert, const int group_num);
float defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index, int group_num);
void defvert_copy(struct MDeformVert *dvert_r, const struct MDeformVert *dvert);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 934c39505cc..fcd61539b23 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -51,6 +51,7 @@ typedef struct Main {
char name[240];
short versionfile, subversionfile;
short minversionfile, minsubversionfile;
+ int revision; /* svn revision of binary that saved file */
struct Library *curlib;
ListBase scene;
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index 8fb80292ffb..5bdea166cce 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -81,5 +81,13 @@ void multires_mdisp_smooth_bounds(struct MDisps *disps);
/* update multires data after topology changing */
void multires_topology_changed(struct Object *ob);
+/**** interpolation stuff ****/
+void old_mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v);
+void mdisp_rot_crn_to_face(int S, int corners, int face_side, float x, float y, float *u, float *v);
+int mdisp_rot_face_to_crn(int corners, int face_side, float u, float v, float *x, float *y);
+void mdisp_apply_weight(int S, int corners, int x, int y, int face_side, float crn_weight[4][2], float *u_r, float *v_r);
+void mdisp_flip_disp(int S, int corners, float axis_x[2], float axis_y[2], float disp[3]);
+void mdisp_join_tris(struct MDisps *dst, struct MDisps *tri1, struct MDisps *tri2);
+
#endif
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index a7ad95b8ffc..f3548888168 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -63,6 +63,13 @@
#define PTCACHE_TYPE_SMOKE_DOMAIN 3
#define PTCACHE_TYPE_SMOKE_HIGHRES 4
+/* high bits reserved for flags that need to be stored in file */
+#define PTCACHE_TYPEFLAG_COMPRESS (1<<16)
+#define PTCACHE_TYPEFLAG_EXTRADATA (1<<17)
+
+#define PTCACHE_TYPEFLAG_TYPEMASK 0x0000FFFF
+#define PTCACHE_TYPEFLAG_FLAGMASK 0xFFFF0000
+
/* PTCache read return code */
#define PTCACHE_READ_EXACT 1
#define PTCACHE_READ_INTERPOLATED 2
@@ -96,7 +103,7 @@ typedef struct PTCacheFile {
FILE *fp;
int totpoint, type, frame, old_format;
- unsigned int data_types;
+ unsigned int data_types, flag;
struct PTCacheData data;
void *cur[BPHYS_TOT_DATA];
@@ -118,15 +125,23 @@ typedef struct PTCacheID {
unsigned int data_types, info_types;
/* copies point data to cache data */
- int (*write_elem)(int index, void *calldata, void **data, int cfra);
+ int (*write_point)(int index, void *calldata, void **data, int cfra);
+ /* copies cache cata to point data */
+ void (*read_point)(int index, void *calldata, void **data, float cfra, float *old_data);
+ /* interpolated between previously read point data and cache data */
+ void (*interpolate_point)(int index, void *calldata, void **data, float cfra, float cfra1, float cfra2, float *old_data);
+
/* copies point data to cache data */
int (*write_stream)(PTCacheFile *pf, void *calldata);
/* copies cache cata to point data */
- void (*read_elem)(int index, void *calldata, void **data, float frs_sec, float cfra, float *old_data);
- /* copies cache cata to point data */
void (*read_stream)(PTCacheFile *pf, void *calldata);
- /* interpolated between previously read point data and cache data */
- void (*interpolate_elem)(int index, void *calldata, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data);
+
+ /* copies custom extradata to cache data */
+ int (*write_extra_data)(void *calldata, struct PTCacheMem *pm, int cfra);
+ /* copies custom extradata to cache data */
+ int (*read_extra_data)(void *calldata, struct PTCacheMem *pm, float cfra);
+ /* copies custom extradata to cache data */
+ int (*interpolate_extra_data)(void *calldata, struct PTCacheMem *pm, float cfra, float cfra1, float cfra2);
/* total number of simulated points (the cfra parameter is just for using same function pointer with totwrite) */
int (*totpoint)(void *calldata, int cfra);
@@ -267,7 +282,7 @@ void BKE_ptcache_data_get(void **data, int type, int index, void *to);
void BKE_ptcache_data_set(void **data, int type, void *from);
/* Main cache reading call. */
-int BKE_ptcache_read(PTCacheID *pid, float cfra, float frs_sec);
+int BKE_ptcache_read(PTCacheID *pid, float cfra);
/* Main cache writing call. */
int BKE_ptcache_write(PTCacheID *pid, int cfra);
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 227f2eadf4c..fdd51dd207f 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -96,7 +96,6 @@ void make_local_action(bAction *act)
if (act->id.us==1) {
act->id.lib= 0;
act->id.flag= LIB_LOCAL;
- //make_local_action_channels(act);
new_id(0, (ID *)act, 0);
return;
}
@@ -376,6 +375,20 @@ bActionGroup *action_groups_find_named (bAction *act, const char name[])
return BLI_findstring(&act->groups, name, offsetof(bActionGroup, name));
}
+/* Clear all 'temp' flags on all groups */
+void action_groups_clear_tempflags (bAction *act)
+{
+ bActionGroup *agrp;
+
+ /* sanity checks */
+ if (ELEM(NULL, act, act->groups.first))
+ return;
+
+ /* flag clearing loop */
+ for (agrp = act->groups.first; agrp; agrp = agrp->next)
+ agrp->flag &= ~AGRP_TEMP;
+}
+
/* *************** Pose channels *************** */
/* usually used within a loop, so we got a N^2 slowdown */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 0e5763e3034..49d3ca833dd 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -277,6 +277,176 @@ void BKE_animdata_make_local(AnimData *adt)
make_local_strips(&nlt->strips);
}
+/* Sub-ID Regrouping ------------------------------------------- */
+
+/* helper heuristic for determining if a path is compatible with the basepath
+ * < path: (str) full RNA-path from some data (usually an F-Curve) to compare
+ * < basepath: (str) shorter path fragment to look for
+ * > returns (bool) whether there is a match
+ */
+static short animpath_matches_basepath (const char path[], const char basepath[])
+{
+ /* we need start of path to be basepath */
+ return (path && basepath) && (strstr(path, basepath) == path);
+}
+
+/* Move F-Curves in src action to dst action, setting up all the necessary groups
+ * for this to happen, but only if the F-Curves being moved have the appropriate
+ * "base path".
+ * - This is used when data moves from one datablock to another, causing the
+ * F-Curves to need to be moved over too
+ */
+void action_move_fcurves_by_basepath (bAction *srcAct, bAction *dstAct, const char basepath[])
+{
+ FCurve *fcu, *fcn=NULL;
+
+ /* sanity checks */
+ if ELEM3(NULL, srcAct, dstAct, basepath) {
+ if (G.f & G_DEBUG) {
+ printf("ERROR: action_partition_fcurves_by_basepath(%p, %p, %p) has insufficient info to work with\n",
+ srcAct, dstAct, basepath);
+ }
+ return;
+ }
+
+ /* clear 'temp' flags on all groups in src, as we'll be needing them later
+ * to identify groups that we've managed to empty out here
+ */
+ action_groups_clear_tempflags(srcAct);
+
+ /* iterate over all src F-Curves, moving over the ones that need to be moved */
+ for (fcu = srcAct->curves.first; fcu; fcu = fcn) {
+ /* store next pointer in case we move stuff */
+ fcn = fcu->next;
+
+ /* should F-Curve be moved over?
+ * - we only need the start of the path to match basepath
+ */
+ if (animpath_matches_basepath(fcu->rna_path, basepath)) {
+ bActionGroup *agrp = NULL;
+
+ /* if grouped... */
+ if (fcu->grp) {
+ /* make sure there will be a matching group on the other side for the migrants */
+ agrp = action_groups_find_named(dstAct, fcu->grp->name);
+
+ if (agrp == NULL) {
+ /* add a new one with a similar name (usually will be the same though) */
+ agrp = action_groups_add_new(dstAct, fcu->grp->name);
+ }
+
+ /* old groups should be tagged with 'temp' flags so they can be removed later
+ * if we remove everything from them
+ */
+ fcu->grp->flag |= AGRP_TEMP;
+ }
+
+ /* perform the migration now */
+ action_groups_remove_channel(srcAct, fcu);
+
+ if (agrp)
+ action_groups_add_channel(dstAct, agrp, fcu);
+ else
+ BLI_addtail(&dstAct->curves, fcu);
+ }
+ }
+
+ /* cleanup groups (if present) */
+ if (srcAct->groups.first) {
+ bActionGroup *agrp, *grp=NULL;
+
+ for (agrp = srcAct->groups.first; agrp; agrp = grp) {
+ grp = agrp->next;
+
+ /* only tagged groups need to be considered - clearing these tags or removing them */
+ if (agrp->flag & AGRP_TEMP) {
+ /* if group is empty and tagged, then we can remove as this operation
+ * moved out all the channels that were formerly here
+ */
+ if (agrp->channels.first == NULL)
+ BLI_freelinkN(&srcAct->groups, agrp);
+ else
+ agrp->flag &= ~AGRP_TEMP;
+ }
+ }
+ }
+}
+
+/* Transfer the animation data from srcID to dstID where the srcID
+ * animation data is based off "basepath", creating new AnimData and
+ * associated data as necessary
+ */
+void BKE_animdata_separate_by_basepath (ID *srcID, ID *dstID, ListBase *basepaths)
+{
+ AnimData *srcAdt=NULL, *dstAdt=NULL;
+ LinkData *ld;
+
+ /* sanity checks */
+ if ELEM(NULL, srcID, dstID) {
+ if (G.f & G_DEBUG)
+ printf("ERROR: no source or destination ID to separate AnimData with\n");
+ return;
+ }
+
+ /* get animdata from src, and create for destination (if needed) */
+ srcAdt = BKE_animdata_from_id(srcID);
+ dstAdt = BKE_id_add_animdata(dstID);
+
+ if ELEM(NULL, srcAdt, dstAdt) {
+ if (G.f & G_DEBUG)
+ printf("ERROR: no AnimData for this pair of ID's\n");
+ return;
+ }
+
+ /* active action */
+ if (srcAdt->action) {
+ /* set up an action if necessary, and name it in a similar way so that it can be easily found again */
+ if (dstAdt->action == NULL) {
+ dstAdt->action = add_empty_action(srcAdt->action->id.name+2);
+ }
+ else if (dstAdt->action == srcAdt->action) {
+ printf("Argh! Source and Destination share animation! ('%s' and '%s' both use '%s') Making new empty action\n",
+ srcID->name, dstID->name, srcAdt->action->id.name);
+
+ // TODO: review this...
+ id_us_min(&dstAdt->action->id);
+ dstAdt->action = add_empty_action(dstAdt->action->id.name+2);
+ }
+
+ /* loop over base paths, trying to fix for each one... */
+ for (ld = basepaths->first; ld; ld = ld->next) {
+ const char *basepath = (const char *)ld->data;
+ action_move_fcurves_by_basepath(srcAdt->action, dstAdt->action, basepath);
+ }
+ }
+
+ /* drivers */
+ if (srcAdt->drivers.first) {
+ FCurve *fcu, *fcn=NULL;
+
+ /* check each driver against all the base paths to see if any should go */
+ for (fcu = srcAdt->drivers.first; fcu; fcu = fcn) {
+ fcn = fcu->next;
+
+ /* try each basepath in turn, but stop on the first one which works */
+ for (ld = basepaths->first; ld; ld = ld->next) {
+ const char *basepath = (const char *)ld->data;
+
+ if (animpath_matches_basepath(fcu->rna_path, basepath)) {
+ /* just need to change lists */
+ BLI_remlink(&srcAdt->drivers, fcu);
+ BLI_addtail(&dstAdt->drivers, fcu);
+
+ // TODO: add depsgraph flushing calls?
+
+ /* can stop now, as moved already */
+ break;
+ }
+ }
+ }
+ }
+}
+
/* Path Validation -------------------------------------------- */
/* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */
@@ -466,46 +636,77 @@ void BKE_animdata_fix_paths_rename (ID *owner_id, AnimData *adt, const char *pre
/* Whole Database Ops -------------------------------------------- */
/* apply the given callback function on all data in main database */
-void BKE_animdata_main_cb (Main *main, ID_AnimData_Edit_Callback func, void *user_data)
+void BKE_animdata_main_cb (Main *mainptr, ID_AnimData_Edit_Callback func, void *user_data)
{
ID *id;
+ /* standard data version */
#define ANIMDATA_IDS_CB(first) \
for (id= first; id; id= id->next) { \
AnimData *adt= BKE_animdata_from_id(id); \
if (adt) func(id, adt, user_data); \
}
- ANIMDATA_IDS_CB(main->nodetree.first); /* nodes */
- ANIMDATA_IDS_CB(main->tex.first); /* textures */
- ANIMDATA_IDS_CB(main->lamp.first); /* lamps */
- ANIMDATA_IDS_CB(main->mat.first); /* materials */
- ANIMDATA_IDS_CB(main->camera.first); /* cameras */
- ANIMDATA_IDS_CB(main->key.first); /* shapekeys */
- ANIMDATA_IDS_CB(main->mball.first); /* metaballs */
- ANIMDATA_IDS_CB(main->curve.first); /* curves */
- ANIMDATA_IDS_CB(main->armature.first); /* armatures */
- ANIMDATA_IDS_CB(main->mesh.first); /* meshes */
- ANIMDATA_IDS_CB(main->particle.first); /* particles */
- ANIMDATA_IDS_CB(main->object.first); /* objects */
- ANIMDATA_IDS_CB(main->world.first); /* worlds */
- ANIMDATA_IDS_CB(main->linestyle.first); /* linestyles */
+ /* "embedded" nodetree cases (i.e. scene/material/texture->nodetree) */
+#define ANIMDATA_NODETREE_IDS_CB(first, NtId_Type) \
+ for (id= first; id; id= id->next) { \
+ AnimData *adt= BKE_animdata_from_id(id); \
+ NtId_Type *ntp= (NtId_Type *)id; \
+ if (ntp->nodetree) { \
+ AnimData *adt2= BKE_animdata_from_id((ID *)ntp); \
+ if (adt2) func(id, adt2, user_data); \
+ } \
+ if (adt) func(id, adt, user_data); \
+ }
- /* scenes */
- for (id= main->scene.first; id; id= id->next) {
- AnimData *adt= BKE_animdata_from_id(id);
- Scene *scene= (Scene *)id;
+ /* nodes */
+ ANIMDATA_IDS_CB(mainptr->nodetree.first);
- /* do compositing nodes first (since these aren't included in main tree) */
- if (scene->nodetree) {
- AnimData *adt2= BKE_animdata_from_id((ID *)scene->nodetree);
- if (adt2) func(id, adt2, user_data);
- }
+ /* textures */
+ ANIMDATA_NODETREE_IDS_CB(mainptr->tex.first, Tex);
- /* now fix scene animation data as per normal */
- if (adt) func((ID *)id, adt, user_data);
+ /* lamps */
+ ANIMDATA_IDS_CB(mainptr->lamp.first);
+
+ /* materials */
+ ANIMDATA_NODETREE_IDS_CB(mainptr->mat.first, Material);
+
+ /* cameras */
+ ANIMDATA_IDS_CB(mainptr->camera.first);
+
+ /* shapekeys */
+ ANIMDATA_IDS_CB(mainptr->key.first);
+
+ /* metaballs */
+ ANIMDATA_IDS_CB(mainptr->mball.first);
+
+ /* curves */
+ ANIMDATA_IDS_CB(mainptr->curve.first);
+
+ /* armatures */
+ ANIMDATA_IDS_CB(mainptr->armature.first);
+
+ /* lattices */
+ ANIMDATA_IDS_CB(mainptr->latt.first);
+
+ /* meshes */
+ ANIMDATA_IDS_CB(mainptr->mesh.first);
+
+ /* particles */
+ ANIMDATA_IDS_CB(mainptr->particle.first);
+
+ /* objects */
+ ANIMDATA_IDS_CB(mainptr->object.first);
+
+ /* worlds */
+ ANIMDATA_IDS_CB(mainptr->world.first);
+
+ /* scenes */
+ ANIMDATA_NODETREE_IDS_CB(mainptr->scene.first, Scene);
+
+ /* line styles */
+ ANIMDATA_IDS_CB(mainptr->linestyle.first);
}
-}
/* Fix all RNA-Paths throughout the database (directly access the Global.main version)
* NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
@@ -527,17 +728,29 @@ void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newNa
BKE_animdata_fix_paths_rename(id, adt, prefix, oldName, newName, 0, 0, 1);\
}
+ /* another version of this macro for nodetrees */
+#define RENAMEFIX_ANIM_NODETREE_IDS(first, NtId_Type) \
+ for (id= first; id; id= id->next) { \
+ AnimData *adt= BKE_animdata_from_id(id); \
+ NtId_Type *ntp= (NtId_Type *)id; \
+ if (ntp->nodetree) { \
+ AnimData *adt2= BKE_animdata_from_id((ID *)ntp); \
+ BKE_animdata_fix_paths_rename((ID *)ntp, adt2, prefix, oldName, newName, 0, 0, 1);\
+ } \
+ BKE_animdata_fix_paths_rename(id, adt, prefix, oldName, newName, 0, 0, 1);\
+ }
+
/* nodes */
RENAMEFIX_ANIM_IDS(mainptr->nodetree.first);
/* textures */
- RENAMEFIX_ANIM_IDS(mainptr->tex.first);
+ RENAMEFIX_ANIM_NODETREE_IDS(mainptr->tex.first, Tex);
/* lamps */
RENAMEFIX_ANIM_IDS(mainptr->lamp.first);
/* materials */
- RENAMEFIX_ANIM_IDS(mainptr->mat.first);
+ RENAMEFIX_ANIM_NODETREE_IDS(mainptr->mat.first, Material);
/* cameras */
RENAMEFIX_ANIM_IDS(mainptr->camera.first);
@@ -554,8 +767,11 @@ void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newNa
/* armatures */
RENAMEFIX_ANIM_IDS(mainptr->armature.first);
+ /* lattices */
+ RENAMEFIX_ANIM_IDS(mainptr->latt.first);
+
/* meshes */
- // TODO...
+ RENAMEFIX_ANIM_IDS(mainptr->mesh.first);
/* particles */
RENAMEFIX_ANIM_IDS(mainptr->particle.first);
@@ -570,21 +786,9 @@ void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newNa
RENAMEFIX_ANIM_IDS(mainptr->linestyle.first);
/* scenes */
- for (id= mainptr->scene.first; id; id= id->next) {
- AnimData *adt= BKE_animdata_from_id(id);
- Scene *scene= (Scene *)id;
-
- /* do compositing nodes first (since these aren't included in main tree) */
- if (scene->nodetree) {
- AnimData *adt2= BKE_animdata_from_id((ID *)scene->nodetree);
- BKE_animdata_fix_paths_rename((ID *)scene->nodetree, adt2, prefix, oldName, newName, 0, 0, 1);
+ RENAMEFIX_ANIM_NODETREE_IDS(mainptr->scene.first, Scene);
}
- /* now fix scene animation data as per normal */
- BKE_animdata_fix_paths_rename((ID *)id, adt, prefix, oldName, newName, 0, 0, 1);
- }
-}
-
/* *********************************** */
/* KeyingSet API */
@@ -689,7 +893,7 @@ KS_Path *BKE_keyingset_add_path (KeyingSet *ks, ID *id, const char group_name[],
/* just store absolute info */
ksp->id= id;
if (group_name)
- BLI_snprintf(ksp->group, 64, group_name);
+ BLI_strncpy(ksp->group, group_name, sizeof(ksp->group));
else
ksp->group[0]= '\0';
@@ -1906,7 +2110,6 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
EVAL_ANIM_IDS(main->camera.first, ADT_RECALC_ANIM);
/* shapekeys */
- // TODO: we probably need the same hack as for curves (ctime-hack)
EVAL_ANIM_IDS(main->key.first, ADT_RECALC_ANIM);
/* metaballs */
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 22d27dc2fde..6b21e45ddd9 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -936,19 +936,15 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
dvert = NULL;
if(armature_def_nr >= 0 && dvert) {
- armature_weight = 0.0f; /* a def group was given, so default to 0 */
- for(j = 0; j < dvert->totweight; j++) {
- if(dvert->dw[j].def_nr == armature_def_nr) {
- armature_weight = dvert->dw[j].weight;
- break;
- }
+ armature_weight= defvert_find_weight(dvert, armature_def_nr);
+
+ if(invert_vgroup) {
+ armature_weight= 1.0f-armature_weight;
}
+
/* hackish: the blending factor can be used for blending with prevCos too */
if(prevCos) {
- if(invert_vgroup)
- prevco_weight= 1.0f-armature_weight;
- else
- prevco_weight= armature_weight;
+ prevco_weight= armature_weight;
armature_weight= 1.0f;
}
}
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index f644b28b137..b283120249e 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -504,7 +504,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
}
/* try to read from cache */
- cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe, scene->r.frs_sec);
+ cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe);
if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
implicit_set_positions(clmd);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index e178beaaa50..f7606a344c9 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -104,6 +104,11 @@ typedef struct LayerTypeInfo {
/* a function to determine file size */
size_t (*filesize)(CDataFile *cdf, void *data, int count);
+
+ /* a function to validate layer contents depending on
+ * sub-elements count
+ */
+ void (*validate)(void *source, int sub_elements);
} LayerTypeInfo;
static void layerCopy_mdeformvert(const void *source, void *dest,
@@ -396,52 +401,6 @@ static void layerDefault_origspace_face(void *data, int count)
osf[i] = default_osf;
}
-/* Adapted from sculptmode.c */
-static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
-{
- int x, y, x2, y2;
- const int st_max = st - 1;
- float urat, vrat, uopp;
- float d[4][3], d2[2][3];
-
- if(u < 0)
- u = 0;
- else if(u >= st)
- u = st_max;
- if(v < 0)
- v = 0;
- else if(v >= st)
- v = st_max;
-
- x = floor(u);
- y = floor(v);
- x2 = x + 1;
- y2 = y + 1;
-
- if(x2 >= st) x2 = st_max;
- if(y2 >= st) y2 = st_max;
-
- urat = u - x;
- vrat = v - y;
- uopp = 1 - urat;
-
- copy_v3_v3(d[0], disps[y * st + x]);
- copy_v3_v3(d[1], disps[y * st + x2]);
- copy_v3_v3(d[2], disps[y2 * st + x]);
- copy_v3_v3(d[3], disps[y2 * st + x2]);
- mul_v3_fl(d[0], uopp);
- mul_v3_fl(d[1], urat);
- mul_v3_fl(d[2], uopp);
- mul_v3_fl(d[3], urat);
-
- add_v3_v3v3(d2[0], d[0], d[1]);
- add_v3_v3v3(d2[1], d[2], d[3]);
- mul_v3_fl(d2[0], 1 - vrat);
- mul_v3_fl(d2[1], vrat);
-
- add_v3_v3v3(out, d2[0], d2[1]);
-}
-
static void layerSwap_mdisps(void *data, const int *ci)
{
MDisps *s = data;
@@ -473,211 +432,6 @@ static void layerSwap_mdisps(void *data, const int *ci)
}
}
-static void mdisp_get_crn_rect(int face_side, float crn[3][4][2])
-{
- float offset = face_side*0.5f - 0.5f;
- float mid[2];
-
- mid[0] = offset * 4 / 3;
- mid[1] = offset * 2 / 3;
-
- crn[0][0][0] = mid[0]; crn[0][0][1] = mid[1];
- crn[0][1][0] = offset; crn[0][1][1] = 0;
- crn[0][2][0] = 0; crn[0][2][1] = 0;
- crn[0][3][0] = offset; crn[0][3][1] = offset;
-
- crn[1][0][0] = mid[0]; crn[1][0][1] = mid[1];
- crn[1][1][0] = offset * 2; crn[1][1][1] = offset;
- crn[1][2][0] = offset * 2; crn[1][2][1] = 0;
- crn[1][3][0] = offset; crn[1][3][1] = 0;
-
- crn[2][0][0] = mid[0]; crn[2][0][1] = mid[1];
- crn[2][1][0] = offset; crn[2][1][1] = offset;
- crn[2][2][0] = offset * 2; crn[2][2][1] = offset * 2;
- crn[2][3][0] = offset * 2; crn[2][3][1] = offset;
-}
-
-static void mdisp_rot_crn_to_face(int S, int corners, int face_side, float x, float y, float *u, float *v)
-{
- float offset = face_side*0.5f - 0.5f;
-
- if(corners == 4) {
- if(S == 1) { *u= offset + x; *v = offset - y; }
- if(S == 2) { *u= offset + y; *v = offset + x; }
- if(S == 3) { *u= offset - x; *v = offset + y; }
- if(S == 0) { *u= offset - y; *v = offset - x; }
- } else {
- float crn[3][4][2], vec[4][2];
- float p[2];
-
- mdisp_get_crn_rect(face_side, crn);
-
- interp_v2_v2v2(vec[0], crn[S][0], crn[S][1], x / offset);
- interp_v2_v2v2(vec[1], crn[S][3], crn[S][2], x / offset);
- interp_v2_v2v2(vec[2], crn[S][0], crn[S][3], y / offset);
- interp_v2_v2v2(vec[3], crn[S][1], crn[S][2], y / offset);
-
- isect_seg_seg_v2_point(vec[0], vec[1], vec[2], vec[3], p);
-
- (*u) = p[0];
- (*v) = p[1];
- }
-}
-
-static int mdisp_pt_in_crn(float p[2], float crn[4][2])
-{
- float v[2][2];
- float a[2][2];
-
- sub_v2_v2v2(v[0], crn[1], crn[0]);
- sub_v2_v2v2(v[1], crn[3], crn[0]);
-
- sub_v2_v2v2(a[0], p, crn[0]);
- sub_v2_v2v2(a[1], crn[2], crn[0]);
-
- if(cross_v2v2(a[0], v[0]) * cross_v2v2(a[1], v[0]) < 0)
- return 0;
-
- if(cross_v2v2(a[0], v[1]) * cross_v2v2(a[1], v[1]) < 0)
- return 0;
-
- return 1;
-}
-
-static void face_to_crn_interp(float u, float v, float v1[2], float v2[2], float v3[2], float v4[2], float *x)
-{
- float a = (v4[1]-v3[1])*v2[0]+(-v4[1]+v3[1])*v1[0]+(-v2[1]+v1[1])*v4[0]+(v2[1]-v1[1])*v3[0];
- float b = (v3[1]-v)*v2[0]+(v4[1]-2*v3[1]+v)*v1[0]+(-v4[1]+v3[1]+v2[1]-v1[1])*u+(v4[0]-v3[0])*v-v1[1]*v4[0]+(-v2[1]+2*v1[1])*v3[0];
- float c = (v3[1]-v)*v1[0]+(-v3[1]+v1[1])*u+v3[0]*v-v1[1]*v3[0];
- float d = b * b - 4 * a * c;
- float x1, x2;
-
- if(a == 0) {
- *x = -c / b;
- return;
- }
-
- x1 = (-b - sqrtf(d)) / (2 * a);
- x2 = (-b + sqrtf(d)) / (2 * a);
-
- *x = maxf(x1, x2);
-}
-
-static int mdisp_rot_face_to_crn(int corners, int face_side, float u, float v, float *x, float *y)
-{
- float offset = face_side*0.5f - 0.5f;
- int S;
-
- if (corners == 4) {
- if(u <= offset && v <= offset) S = 0;
- else if(u > offset && v <= offset) S = 1;
- else if(u > offset && v > offset) S = 2;
- else if(u <= offset && v >= offset) S = 3;
-
- if(S == 0) {
- *y = offset - u;
- *x = offset - v;
- } else if(S == 1) {
- *x = u - offset;
- *y = offset - v;
- } else if(S == 2) {
- *y = u - offset;
- *x = v - offset;
- } else if(S == 3) {
- *x= offset - u;
- *y = v - offset;
- }
- } else {
- float crn[3][4][2];
- float p[2] = {u, v};
-
- mdisp_get_crn_rect(face_side, crn);
-
- for (S = 0; S < 3; ++S) {
- if (mdisp_pt_in_crn(p, crn[S]))
- break;
- }
-
- face_to_crn_interp(u, v, crn[S][0], crn[S][1], crn[S][3], crn[S][2], &p[0]);
- face_to_crn_interp(u, v, crn[S][0], crn[S][3], crn[S][1], crn[S][2], &p[1]);
-
- *x = p[0] * offset;
- *y = p[1] * offset;
- }
-
- return S;
-}
-
-static void mdisp_apply_weight(int S, int corners, int x, int y, int face_side,
- float crn_weight[4][2], float *u_r, float *v_r)
-{
- float u, v, xl, yl;
- float mid1[2], mid2[2], mid3[2];
-
- mdisp_rot_crn_to_face(S, corners, face_side, x, y, &u, &v);
-
- if(corners == 4) {
- xl = u / (face_side - 1);
- yl = v / (face_side - 1);
-
- mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
- mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
- mid2[0] = crn_weight[3][0] * (1 - xl) + crn_weight[2][0] * xl;
- mid2[1] = crn_weight[3][1] * (1 - xl) + crn_weight[2][1] * xl;
- mid3[0] = mid1[0] * (1 - yl) + mid2[0] * yl;
- mid3[1] = mid1[1] * (1 - yl) + mid2[1] * yl;
- } else {
- yl = v / (face_side - 1);
-
- if(v == face_side - 1) xl = 1;
- else xl = 1 - (face_side - 1 - u) / (face_side - 1 - v);
-
- mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
- mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
- mid3[0] = mid1[0] * (1 - yl) + crn_weight[2][0] * yl;
- mid3[1] = mid1[1] * (1 - yl) + crn_weight[2][1] * yl;
- }
-
- *u_r = mid3[0];
- *v_r = mid3[1];
-}
-
-static void mdisp_flip_disp(int S, int corners, float axis_x[2], float axis_y[2], float disp[3])
-{
- float crn_x[2], crn_y[2];
- float vx[2], vy[2], coord[2];
-
- if (corners == 4) {
- float x[4][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
- float y[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
-
- copy_v2_v2(crn_x, x[S]);
- copy_v2_v2(crn_y, y[S]);
-
- mul_v2_v2fl(vx, crn_x, disp[0]);
- mul_v2_v2fl(vy, crn_y, disp[1]);
- add_v2_v2v2(coord, vx, vy);
-
- project_v2_v2v2(vx, coord, axis_x);
- project_v2_v2v2(vy, coord, axis_y);
-
- disp[0] = len_v2(vx);
- disp[1] = len_v2(vy);
-
- if(dot_v2v2(vx, axis_x) < 0)
- disp[0] = -disp[0];
-
- if(dot_v2v2(vy, axis_y) < 0)
- disp[1] = -disp[1];
- } else {
- /* XXX: it was very overhead code to support displacement flipping
- for case of tris without visible profit.
- Maybe its not really big limitation? for now? (nazgul) */
- disp[0] = 0;
- disp[1] = 0;
- }
-}
-
static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
float *sub_weights, int count, void *dest)
{
@@ -687,16 +441,55 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
int i, x, y;
int side, S, dst_corners, src_corners;
float crn_weight[4][2];
- float (*sw)[4] = NULL;
+ float (*sw)[4] = (void*)sub_weights;
float (*disps)[3], (*out)[3];
s = sources[0];
dst_corners = multires_mdisp_corners(d);
src_corners = multires_mdisp_corners(s);
- /* XXX: For now, some restrictions on the input
- should be implemented to allow quad<->tris face conversion */
- if(count != 1 || !sub_weights || dst_corners != src_corners) {
+ if(sub_weights && count == 2 && src_corners == 3) {
+ src_corners = multires_mdisp_corners(sources[1]);
+
+ /* special case -- converting two triangles to quad */
+ if(src_corners == 3 && dst_corners == 4) {
+ MDisps tris[2];
+ int vindex[4] = {0};
+
+ S = 0;
+ for(i = 0; i < 2; i++)
+ for(y = 0; y < 4; y++)
+ for(x = 0; x < 4; x++)
+ if(sw[x+i*4][y])
+ vindex[x] = y;
+
+ for(i = 0; i < 2; i++) {
+ float sw[4][4] = {{0}};
+ int a = 7 & ~(1 << vindex[i*2] | 1 << vindex[i*2+1]);
+
+ sw[0][vindex[i*2+1]] = 1;
+ sw[1][vindex[i*2]] = 1;
+
+ for(x = 0; x < 3; x++)
+ if(a & (1 << x))
+ sw[2][x] = 1;
+
+ tris[i] = *((MDisps*)sources[i]);
+ tris[i].disps = MEM_dupallocN(tris[i].disps);
+ layerInterp_mdisps(&sources[i], NULL, (float*)sw, 1, &tris[i]);
+ }
+
+ mdisp_join_tris(d, &tris[0], &tris[1]);
+
+ for(i = 0; i < 2; i++)
+ MEM_freeN(tris[i].disps);
+
+ return;
+ }
+ }
+
+ /* For now, some restrictions on the input */
+ if(count != 1 || !sub_weights) {
for(i = 0; i < d->totdisp; ++i)
zero_v3(d->disps[i]);
@@ -739,7 +532,7 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
mdisp_apply_weight(S, dst_corners, x, y, st, crn_weight, &face_u, &face_v);
crn = mdisp_rot_face_to_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
- mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v);
+ old_mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v);
mdisp_flip_disp(crn, dst_corners, axis_x, axis_y, *out);
}
}
@@ -768,6 +561,20 @@ static void layerCopy_mdisps(const void *source, void *dest, int count)
}
}
+static void layerValidate_mdisps(void *data, int sub_elements)
+{
+ MDisps *disps = data;
+ if(disps->disps) {
+ int corners = multires_mdisp_corners(disps);
+
+ if(corners != sub_elements) {
+ MEM_freeN(disps->disps);
+ disps->totdisp = disps->totdisp / corners * sub_elements;
+ disps->disps = MEM_callocN(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
+ }
+ }
+}
+
static void layerFree_mdisps(void *data, int count, int UNUSED(size))
{
int i;
@@ -1019,7 +826,8 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
{sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
- layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps},
+ layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps,
+ layerFilesize_mdisps, layerValidate_mdisps},
{sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
{sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
@@ -1942,6 +1750,18 @@ void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
}
}
+void CustomData_em_validate_data(CustomData *data, void *block, int sub_elements)
+{
+ int i;
+ for(i = 0; i < data->totlayer; i++) {
+ const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
+ char *leayer_data = (char*)block + data->layers[i].offset;
+
+ if(typeInfo->validate)
+ typeInfo->validate(leayer_data, sub_elements);
+ }
+}
+
void *CustomData_em_get(const CustomData *data, void *block, int type)
{
int layer_index;
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index ad797736a85..937681fcdc3 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -448,7 +448,7 @@ void flip_side_name (char *name, const char *from_name, int strip_number)
sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
}
-float defvert_find_weight(const struct MDeformVert *dvert, int group_num)
+float defvert_find_weight(const struct MDeformVert *dvert, const int group_num)
{
MDeformWeight *dw= defvert_find_index(dvert, group_num);
return dw ? dw->weight : 0.0f;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 325e64bf768..f2bc586f15c 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1329,7 +1329,7 @@ DriverVar *driver_add_new_variable (ChannelDriver *driver)
#ifdef WITH_PYTHON
/* since driver variables are cached, the expression needs re-compiling too */
- if(driver->type==DRIVER_TYPE_PYTHON)
+ if (driver->type==DRIVER_TYPE_PYTHON)
driver->flag |= DRIVER_FLAG_RENAMEVAR;
#endif
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 1ed8241325e..0376d75d651 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -1009,9 +1009,13 @@ FModifier *add_fmodifier (ListBase *modifiers, int type)
fcm->flag = FMODIFIER_FLAG_EXPANDED;
BLI_addtail(modifiers, fcm);
+ /* tag modifier as "active" if no other modifiers exist in the stack yet */
+ if (modifiers->first == modifiers->last)
+ fcm->flag |= FMODIFIER_FLAG_ACTIVE;
+
/* add modifier's data */
fcm->data= MEM_callocN(fmi->size, fmi->structName);
-
+
/* init custom settings if necessary */
if (fmi->new_data)
fmi->new_data(fcm->data);
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 500ccf0781b..ec63975a3c0 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -670,7 +670,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
VFont *vfont, *oldvfont;
VFontData *vfd= NULL;
Curve *cu;
- CharInfo *info, *custrinfo;
+ CharInfo *info = NULL, *custrinfo;
TextBox *tb;
VChar *che;
struct chartrans *chartransdata=NULL, *ct;
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index c18085b2d73..8cdfbaf9e2a 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -1191,7 +1191,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
if(key->slurph && key->type!=KEY_RELATIVE) {
Nurb *nu;
- int mode, i= 0, remain= 0, estep, count;
+ int mode=0, i= 0, remain= 0, estep=0, count=0;
delta= (float)key->slurph / tot;
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 03cbd9e41fd..8658d7e482f 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -737,7 +737,7 @@ void accum_mballfaces(int i1, int i2, int i3, int i4)
void *new_pgn_element(int size)
{
/* during polygonize 1000s of elements are allocated
- * and never freed inbetween. Freeing only done at the end.
+ * and never freed in between. Freeing only done at the end.
*/
int blocksize= 16384;
static int offs= 0; /* the current free address */
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 2224b3d8d49..84350127968 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -837,7 +837,7 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int loca
***************************/
/* Adapted from sculptmode.c */
-static void old_mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
+void old_mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
{
int x, y, x2, y2;
const int st_max = st - 1;
@@ -1774,3 +1774,254 @@ void multires_mdisp_smooth_bounds(MDisps *disps)
}
}
}
+
+/***************** Multires interpolation stuff *****************/
+
+static void mdisp_get_crn_rect(int face_side, float crn[3][4][2])
+{
+ float offset = face_side*0.5f - 0.5f;
+ float mid[2];
+
+ mid[0] = offset * 4 / 3;
+ mid[1] = offset * 2 / 3;
+
+ crn[0][0][0] = mid[0]; crn[0][0][1] = mid[1];
+ crn[0][1][0] = offset; crn[0][1][1] = 0;
+ crn[0][2][0] = 0; crn[0][2][1] = 0;
+ crn[0][3][0] = offset; crn[0][3][1] = offset;
+
+ crn[1][0][0] = mid[0]; crn[1][0][1] = mid[1];
+ crn[1][1][0] = offset * 2; crn[1][1][1] = offset;
+ crn[1][2][0] = offset * 2; crn[1][2][1] = 0;
+ crn[1][3][0] = offset; crn[1][3][1] = 0;
+
+ crn[2][0][0] = mid[0]; crn[2][0][1] = mid[1];
+ crn[2][1][0] = offset; crn[2][1][1] = offset;
+ crn[2][2][0] = offset * 2; crn[2][2][1] = offset * 2;
+ crn[2][3][0] = offset * 2; crn[2][3][1] = offset;
+}
+
+static int mdisp_pt_in_crn(float p[2], float crn[4][2])
+{
+ float v[2][2];
+ float a[2][2];
+
+ sub_v2_v2v2(v[0], crn[1], crn[0]);
+ sub_v2_v2v2(v[1], crn[3], crn[0]);
+
+ sub_v2_v2v2(a[0], p, crn[0]);
+ sub_v2_v2v2(a[1], crn[2], crn[0]);
+
+ if(cross_v2v2(a[0], v[0]) * cross_v2v2(a[1], v[0]) < 0)
+ return 0;
+
+ if(cross_v2v2(a[0], v[1]) * cross_v2v2(a[1], v[1]) < 0)
+ return 0;
+
+ return 1;
+}
+
+static void face_to_crn_interp(float u, float v, float v1[2], float v2[2], float v3[2], float v4[2], float *x)
+{
+ float a = (v4[1]-v3[1])*v2[0]+(-v4[1]+v3[1])*v1[0]+(-v2[1]+v1[1])*v4[0]+(v2[1]-v1[1])*v3[0];
+ float b = (v3[1]-v)*v2[0]+(v4[1]-2*v3[1]+v)*v1[0]+(-v4[1]+v3[1]+v2[1]-v1[1])*u+(v4[0]-v3[0])*v-v1[1]*v4[0]+(-v2[1]+2*v1[1])*v3[0];
+ float c = (v3[1]-v)*v1[0]+(-v3[1]+v1[1])*u+v3[0]*v-v1[1]*v3[0];
+ float d = b * b - 4 * a * c;
+ float x1, x2;
+
+ if(a == 0) {
+ *x = -c / b;
+ return;
+ }
+
+ x1 = (-b - sqrtf(d)) / (2 * a);
+ x2 = (-b + sqrtf(d)) / (2 * a);
+
+ *x = maxf(x1, x2);
+}
+
+void mdisp_rot_crn_to_face(int S, int corners, int face_side, float x, float y, float *u, float *v)
+{
+ float offset = face_side*0.5f - 0.5f;
+
+ if(corners == 4) {
+ if(S == 1) { *u= offset + x; *v = offset - y; }
+ if(S == 2) { *u= offset + y; *v = offset + x; }
+ if(S == 3) { *u= offset - x; *v = offset + y; }
+ if(S == 0) { *u= offset - y; *v = offset - x; }
+ } else {
+ float crn[3][4][2], vec[4][2];
+ float p[2];
+
+ mdisp_get_crn_rect(face_side, crn);
+
+ interp_v2_v2v2(vec[0], crn[S][0], crn[S][1], x / offset);
+ interp_v2_v2v2(vec[1], crn[S][3], crn[S][2], x / offset);
+ interp_v2_v2v2(vec[2], crn[S][0], crn[S][3], y / offset);
+ interp_v2_v2v2(vec[3], crn[S][1], crn[S][2], y / offset);
+
+ isect_seg_seg_v2_point(vec[0], vec[1], vec[2], vec[3], p);
+
+ (*u) = p[0];
+ (*v) = p[1];
+ }
+}
+
+int mdisp_rot_face_to_crn(int corners, int face_side, float u, float v, float *x, float *y)
+{
+ float offset = face_side*0.5f - 0.5f;
+ int S;
+
+ if (corners == 4) {
+ if(u <= offset && v <= offset) S = 0;
+ else if(u > offset && v <= offset) S = 1;
+ else if(u > offset && v > offset) S = 2;
+ else if(u <= offset && v >= offset) S = 3;
+
+ if(S == 0) {
+ *y = offset - u;
+ *x = offset - v;
+ } else if(S == 1) {
+ *x = u - offset;
+ *y = offset - v;
+ } else if(S == 2) {
+ *y = u - offset;
+ *x = v - offset;
+ } else if(S == 3) {
+ *x= offset - u;
+ *y = v - offset;
+ }
+ } else {
+ float crn[3][4][2];
+ float p[2] = {u, v};
+
+ mdisp_get_crn_rect(face_side, crn);
+
+ for (S = 0; S < 3; ++S) {
+ if (mdisp_pt_in_crn(p, crn[S]))
+ break;
+ }
+
+ face_to_crn_interp(u, v, crn[S][0], crn[S][1], crn[S][3], crn[S][2], &p[0]);
+ face_to_crn_interp(u, v, crn[S][0], crn[S][3], crn[S][1], crn[S][2], &p[1]);
+
+ *x = p[0] * offset;
+ *y = p[1] * offset;
+ }
+
+ return S;
+}
+
+void mdisp_apply_weight(int S, int corners, int x, int y, int face_side,
+ float crn_weight[4][2], float *u_r, float *v_r)
+{
+ float u, v, xl, yl;
+ float mid1[2], mid2[2], mid3[2];
+
+ mdisp_rot_crn_to_face(S, corners, face_side, x, y, &u, &v);
+
+ if(corners == 4) {
+ xl = u / (face_side - 1);
+ yl = v / (face_side - 1);
+
+ mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
+ mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
+ mid2[0] = crn_weight[3][0] * (1 - xl) + crn_weight[2][0] * xl;
+ mid2[1] = crn_weight[3][1] * (1 - xl) + crn_weight[2][1] * xl;
+ mid3[0] = mid1[0] * (1 - yl) + mid2[0] * yl;
+ mid3[1] = mid1[1] * (1 - yl) + mid2[1] * yl;
+ } else {
+ yl = v / (face_side - 1);
+
+ if(v == face_side - 1) xl = 1;
+ else xl = 1 - (face_side - 1 - u) / (face_side - 1 - v);
+
+ mid1[0] = crn_weight[0][0] * (1 - xl) + crn_weight[1][0] * xl;
+ mid1[1] = crn_weight[0][1] * (1 - xl) + crn_weight[1][1] * xl;
+ mid3[0] = mid1[0] * (1 - yl) + crn_weight[2][0] * yl;
+ mid3[1] = mid1[1] * (1 - yl) + crn_weight[2][1] * yl;
+ }
+
+ *u_r = mid3[0];
+ *v_r = mid3[1];
+}
+
+void mdisp_flip_disp(int S, int corners, float axis_x[2], float axis_y[2], float disp[3])
+{
+ float crn_x[2], crn_y[2];
+ float vx[2], vy[2], coord[2];
+
+ if (corners == 4) {
+ float x[4][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
+ float y[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
+
+ copy_v2_v2(crn_x, x[S]);
+ copy_v2_v2(crn_y, y[S]);
+
+ mul_v2_v2fl(vx, crn_x, disp[0]);
+ mul_v2_v2fl(vy, crn_y, disp[1]);
+ add_v2_v2v2(coord, vx, vy);
+
+ project_v2_v2v2(vx, coord, axis_x);
+ project_v2_v2v2(vy, coord, axis_y);
+
+ disp[0] = len_v2(vx);
+ disp[1] = len_v2(vy);
+
+ if(dot_v2v2(vx, axis_x) < 0)
+ disp[0] = -disp[0];
+
+ if(dot_v2v2(vy, axis_y) < 0)
+ disp[1] = -disp[1];
+ } else {
+ /* XXX: it was very overhead code to support displacement flipping
+ for case of tris without visible profit.
+ Maybe its not really big limitation? for now? (nazgul) */
+ disp[0] = 0;
+ disp[1] = 0;
+ }
+}
+
+/* Join two triangular displacements into one quad
+ Corners mapping:
+ 2 -------- 3
+ | \ tri2 |
+ | \ |
+ | tri1 \ |
+ 0 -------- 1 */
+void mdisp_join_tris(MDisps *dst, MDisps *tri1, MDisps *tri2)
+{
+ int side, st;
+ int S, x, y, crn;
+ float face_u, face_v, crn_u, crn_v;
+ float (*out)[3];
+ MDisps *src;
+
+ if(dst->disps)
+ MEM_freeN(dst->disps);
+
+ side = sqrt(tri1->totdisp / 3);
+ st = (side<<1)-1;
+
+ dst->totdisp = 4 * side * side;
+ out = dst->disps = MEM_callocN(3*dst->totdisp*sizeof(float), "join disps");
+
+ for(S = 0; S < 4; S++)
+ for(y = 0; y < side; ++y)
+ for(x = 0; x < side; ++x, ++out) {
+ mdisp_rot_crn_to_face(S, 4, st, x, y, &face_u, &face_v);
+ face_u = st - 1 - face_u;
+
+ if(face_v > face_u) {
+ src = tri2;
+ face_u = st - 1 - face_u;
+ face_v = st - 1 - face_v;
+ } else src = tri1;
+
+ crn = mdisp_rot_face_to_crn(3, st, face_u, face_v, &crn_u, &crn_v);
+
+ old_mdisps_bilinear((*out), &src->disps[crn*side*side], side, crn_u, crn_v);
+ (*out)[0] = 0;
+ (*out)[1] = 0;
+ }
+}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index f52a538cc00..db11b42ee1e 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -36,11 +36,13 @@
#include <string.h>
#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
#include "RNA_access.h"
+#include "BKE_animsys.h"
+#include "BKE_action.h"
#include "BKE_fcurve.h"
-#include "BKE_animsys.h" /* BKE_free_animdata only */
#include "PIL_time.h"
@@ -460,6 +462,7 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
bNode *node, *gnode, *nextn;
bNodeSocket *sock;
bNodeTree *ngroup;
+ ListBase anim_basepaths = {NULL, NULL};
float min[2], max[2];
int totnode=0;
@@ -502,11 +505,27 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
for(node= ntree->nodes.first; node; node= nextn) {
nextn= node->next;
if(node->flag & NODE_SELECT) {
+ /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
+ * if the old nodetree has animation data which potentially covers this node
+ */
+ if (ntree->adt) {
+ PointerRNA ptr;
+ char *path;
+
+ RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
+ path = RNA_path_from_ID_to_struct(&ptr);
+
+ if (path)
+ BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+ }
+
+ /* change node-collection membership */
BLI_remlink(&ntree->nodes, node);
BLI_addtail(&ngroup->nodes, node);
+
node->locx-= 0.5f*(min[0]+max[0]);
node->locy-= 0.5f*(min[1]+max[1]);
-
+
/* set socket own_index to zero since it can still have a value
* from being in a group before, otherwise it doesn't get a unique
* index in group_verify_own_indices */
@@ -526,6 +545,21 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
}
}
+ /* move animation data over */
+ if (ntree->adt) {
+ LinkData *ld, *ldn=NULL;
+
+ BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);
+
+ /* paths + their wrappers need to be freed */
+ for (ld = anim_basepaths.first; ld; ld = ld->next) {
+ ldn = ld->next;
+
+ MEM_freeN(ld->data);
+ BLI_freelinkN(&anim_basepaths, ld);
+ }
+ }
+
/* now we can make own group typeinfo */
ntreeMakeOwnType(ngroup);
@@ -771,6 +805,7 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
bNodeLink *link, *linkn;
bNode *node, *nextn;
bNodeTree *ngroup, *wgroup;
+ ListBase anim_basepaths = {NULL, NULL};
int index;
ngroup= (bNodeTree *)gnode->id;
@@ -779,16 +814,38 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
/* clear new pointers, set in copytree */
for(node= ntree->nodes.first; node; node= node->next)
node->new_node= NULL;
-
+
+ /* wgroup is a temporary copy of the NodeTree we're merging in
+ * - all of wgroup's nodes are transferred across to their new home
+ * - ngroup (i.e. the source NodeTree) is left unscathed
+ */
wgroup= ntreeCopyTree(ngroup, 0);
/* add the nodes into the ntree */
for(node= wgroup->nodes.first; node; node= nextn) {
nextn= node->next;
+
+ /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
+ * if the old nodetree has animation data which potentially covers this node
+ */
+ if (wgroup->adt) {
+ PointerRNA ptr;
+ char *path;
+
+ RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
+ path = RNA_path_from_ID_to_struct(&ptr);
+
+ if (path)
+ BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+ }
+
+ /* migrate node */
BLI_remlink(&wgroup->nodes, node);
BLI_addtail(&ntree->nodes, node);
+
node->locx+= gnode->locx;
node->locy+= gnode->locy;
+
node->flag |= NODE_SELECT;
}
/* and the internal links */
@@ -797,6 +854,29 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
BLI_remlink(&wgroup->links, link);
BLI_addtail(&ntree->links, link);
}
+
+ /* and copy across the animation */
+ if (wgroup->adt) {
+ LinkData *ld, *ldn=NULL;
+ bAction *waction;
+
+ /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
+ waction = wgroup->adt->action = copy_action(wgroup->adt->action);
+
+ /* now perform the moving */
+ BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
+
+ /* paths + their wrappers need to be freed */
+ for (ld = anim_basepaths.first; ld; ld = ld->next) {
+ ldn = ld->next;
+
+ MEM_freeN(ld->data);
+ BLI_freelinkN(&anim_basepaths, ld);
+ }
+
+ /* free temp action too */
+ free_libblock(&G.main->action, waction);
+ }
/* restore links to and from the gnode */
for(link= ntree->links.first; link; link= link->next) {
@@ -2474,6 +2554,25 @@ static bNode *getExecutableNode(bNodeTree *ntree)
return NULL;
}
+/* check if texture nodes need exec or end */
+static void ntree_composite_texnode(bNodeTree *ntree, int init)
+{
+ bNode *node;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->type==CMP_NODE_TEXTURE && node->id) {
+ Tex *tex= (Tex *)node->id;
+ if(tex->nodetree && tex->use_nodes) {
+ /* has internal flag to detect it only does it once */
+ if(init)
+ ntreeBeginExecTree(tex->nodetree);
+ else
+ ntreeEndExecTree(tex->nodetree);
+ }
+ }
+ }
+
+}
/* optimized tree execute test for compositing */
void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
@@ -2489,6 +2588,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
ntreeInitPreview(ntree, 0, 0);
ntreeBeginExecTree(ntree);
+ ntree_composite_texnode(ntree, 1);
/* prevent unlucky accidents */
if(G.background)
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index a7506f2114b..95e14542e28 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1158,7 +1158,7 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic
pind->dietime = (key + pa->totkey - 1)->time;
}
else if(pind->cache) {
- float start, end;
+ float start=0.0f, end=0.0f;
get_pointcache_keys_for_time(ob, pind->cache, &pind->pm, -1, 0.0f, NULL, NULL);
pind->birthtime = pa ? pa->time : pind->cache->startframe;
pind->dietime = pa ? pa->dietime : pind->cache->endframe;
@@ -2807,7 +2807,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
float birthtime = 0.0, dietime = 0.0;
float t, time = 0.0, dfra = 1.0, frs_sec = sim->scene->r.frs_sec;
float col[4] = {0.5f, 0.5f, 0.5f, 1.0f};
- float prev_tangent[3], hairmat[4][4];
+ float prev_tangent[3] = {0.0f, 0.0f, 0.0f}, hairmat[4][4];
float rotmat[3][3];
int k;
int steps = (int)pow(2.0, (double)(psys->renderdata ? part->ren_step : part->draw_step));
@@ -3025,7 +3025,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
float birthtime = 0.0, dietime = 0.0;
float t, time = 0.0, keytime = 0.0, frs_sec;
- float hairmat[4][4], rotmat[3][3], prev_tangent[3];
+ float hairmat[4][4], rotmat[3][3], prev_tangent[3] = {0.0f, 0.0f, 0.0f};
int k, i;
int steps = (int)pow(2.0, (double)pset->draw_step);
int totpart = edit->totpoint, recalc_set=0;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 1f36f0845a2..f0af7e8684b 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -350,7 +350,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link);
}
else { /* FROM_FACE/FROM_VOLUME */
- /* Note that somtimes the pa->num is over the nodearray size, this is bad, maybe there is a better place to fix this,
+ /* Note that sometimes the pa->num is over the nodearray size, this is bad, maybe there is a better place to fix this,
* but for now passing NULL is OK. every face will be searched for the particle so its slower - Campbell */
pa->num_dmcache= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, pa->num < totelem ? nodearray[pa->num] : NULL);
}
@@ -2244,7 +2244,9 @@ void psys_make_temp_pointcache(Object *ob, ParticleSystem *psys)
if(cache->flag & PTCACHE_DISK_CACHE && cache->mem_cache.first == NULL) {
PTCacheID pid;
BKE_ptcache_id_from_particles(&pid, ob, psys);
+ cache->flag &= ~PTCACHE_DISK_CACHE;
BKE_ptcache_disk_to_mem(&pid);
+ cache->flag |= PTCACHE_DISK_CACHE;
}
}
static void psys_clear_temp_pointcache(ParticleSystem *psys)
@@ -3795,7 +3797,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
/* 2. try to read from the cache */
if(pid) {
- int cache_result = BKE_ptcache_read(pid, cache_cfra, sim->scene->r.frs_sec);
+ int cache_result = BKE_ptcache_read(pid, cache_cfra);
if(ELEM(cache_result, PTCACHE_READ_EXACT, PTCACHE_READ_INTERPOLATED)) {
cached_step(sim, cfra);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 7a8d3a8b19c..b8e8508da26 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -96,7 +96,7 @@
#define DURIAN_POINTCACHE_LIB_OK 1
int ptcache_data_size[] = {
- sizeof(int), // BPHYS_DATA_INDEX
+ sizeof(uint32_t), // BPHYS_DATA_INDEX
3 * sizeof(float), // BPHYS_DATA_LOCATION:
3 * sizeof(float), // BPHYS_DATA_VELOCITY:
4 * sizeof(float), // BPHYS_DATA_ROTATION:
@@ -107,30 +107,38 @@ int ptcache_data_size[] = {
};
/* forward declerations */
-static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, int size);
-static int ptcache_file_read(PTCacheFile *pf, void *f, size_t tot, int size);
+static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result, size_t len);
+static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, size_t in_len, unsigned char *out, int mode);
+static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, size_t size);
+static int ptcache_file_read(PTCacheFile *pf, void *f, size_t tot, size_t size);
/* Common functions */
static int ptcache_basic_header_read(PTCacheFile *pf)
{
+ uint32_t totpoint, data_types;
int error=0;
/* Custom functions should read these basic elements too! */
- if(!error && !fread(&pf->totpoint, sizeof(int), 1, pf->fp))
+ if(!error && !fread(&totpoint, sizeof(int), 1, pf->fp))
error = 1;
+ pf->totpoint = totpoint;
- if(!error && !fread(&pf->data_types, sizeof(int), 1, pf->fp))
+ if(!error && !fread(&data_types, sizeof(int), 1, pf->fp))
error = 1;
+ pf->data_types = data_types;
return !error;
}
static int ptcache_basic_header_write(PTCacheFile *pf)
{
+ uint32_t totpoint = pf->totpoint;
+ uint32_t data_types = pf->data_types;
+
/* Custom functions should write these basic elements too! */
- if(!fwrite(&pf->totpoint, sizeof(int), 1, pf->fp))
+ if(!fwrite(&totpoint, sizeof(int), 1, pf->fp))
return 0;
- if(!fwrite(&pf->data_types, sizeof(int), 1, pf->fp))
+ if(!fwrite(&data_types, sizeof(int), 1, pf->fp))
return 0;
return 1;
@@ -146,7 +154,7 @@ static int ptcache_softbody_write(int index, void *soft_v, void **data, int UNU
return 1;
}
-static void ptcache_softbody_read(int index, void *soft_v, void **data, float UNUSED(frs_sec), float UNUSED(cfra), float *old_data)
+static void ptcache_softbody_read(int index, void *soft_v, void **data, float UNUSED(cfra), float *old_data)
{
SoftBody *soft= soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -160,7 +168,7 @@ static void ptcache_softbody_read(int index, void *soft_v, void **data, float UN
PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, bp->vec);
}
}
-static void ptcache_softbody_interpolate(int index, void *soft_v, void **data, float UNUSED(frs_sec), 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, float *old_data)
{
SoftBody *soft= soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -244,11 +252,12 @@ static int ptcache_particle_write(int index, void *psys_v, void **data, int cfr
/* return flag 1+1=2 for newly born particles to copy exact birth location to previously cached frame */
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 frs_sec, float cfra, float *old_data)
+static void ptcache_particle_read(int index, void *psys_v, void **data, float cfra, float *old_data)
{
ParticleSystem *psys= psys_v;
ParticleData *pa;
BoidParticle *boid;
+ float timestep = 0.04f*psys->part->timetweak;
if(index >= psys->totpart)
return;
@@ -289,11 +298,11 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float fr
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) {
if(cfra > pa->prev_state.time) {
sub_v3_v3v3(pa->state.vel, pa->state.co, pa->prev_state.co);
- mul_v3_fl(pa->state.vel, (cfra - pa->prev_state.time) / frs_sec);
+ mul_v3_fl(pa->state.vel, (cfra - pa->prev_state.time) * timestep);
}
else {
sub_v3_v3v3(pa->state.vel, pa->prev_state.co, pa->state.co);
- mul_v3_fl(pa->state.vel, (pa->prev_state.time - cfra) / frs_sec);
+ mul_v3_fl(pa->state.vel, (pa->prev_state.time - cfra) * timestep);
}
}
@@ -302,12 +311,12 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float fr
vec_to_quat( pa->state.rot,pa->state.vel, OB_NEGX, OB_POSZ);
}
}
-static void ptcache_particle_interpolate(int index, void *psys_v, void **data, float frs_sec, 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, float *old_data)
{
ParticleSystem *psys= psys_v;
ParticleData *pa;
ParticleKey keys[4];
- float dfra;
+ float dfra, timestep = 0.04f*psys->part->timetweak;
if(index >= psys->totpart)
return;
@@ -335,11 +344,11 @@ static void ptcache_particle_interpolate(int index, void *psys_v, void **data, f
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) {
if(keys[1].time > keys[2].time) {
sub_v3_v3v3(keys[2].vel, keys[1].co, keys[2].co);
- mul_v3_fl(keys[2].vel, (keys[1].time - keys[2].time) / frs_sec);
+ mul_v3_fl(keys[2].vel, (keys[1].time - keys[2].time) * timestep);
}
else {
sub_v3_v3v3(keys[2].vel, keys[2].co, keys[1].co);
- mul_v3_fl(keys[2].vel, (keys[2].time - keys[1].time) / frs_sec);
+ mul_v3_fl(keys[2].vel, (keys[2].time - keys[1].time) * timestep);
}
}
@@ -353,13 +362,13 @@ static void ptcache_particle_interpolate(int index, void *psys_v, void **data, f
dfra = cfra2 - cfra1;
- mul_v3_fl(keys[1].vel, dfra / frs_sec);
- mul_v3_fl(keys[2].vel, dfra / frs_sec);
+ mul_v3_fl(keys[1].vel, dfra * timestep);
+ mul_v3_fl(keys[2].vel, dfra * timestep);
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, frs_sec / dfra);
+ mul_v3_fl(pa->state.vel, 1.f / (dfra * timestep));
pa->state.time = cfra;
}
@@ -376,6 +385,9 @@ static int ptcache_particle_totwrite(void *psys_v, int cfra)
int p, step = psys->pointcache->step;
int totwrite = 0;
+ if(cfra == 0)
+ return psys->totpart;
+
for(p=0; p<psys->totpart; p++,pa++)
totwrite += (cfra >= pa->time - step && cfra <= pa->dietime + step);
@@ -395,7 +407,7 @@ static int ptcache_cloth_write(int index, void *cloth_v, void **data, int UNUSE
return 1;
}
-static void ptcache_cloth_read(int index, void *cloth_v, void **data, float UNUSED(frs_sec), float UNUSED(cfra), float *old_data)
+static void ptcache_cloth_read(int index, void *cloth_v, void **data, float UNUSED(cfra), float *old_data)
{
ClothModifierData *clmd= cloth_v;
Cloth *cloth= clmd->clothObject;
@@ -412,7 +424,7 @@ static void ptcache_cloth_read(int index, void *cloth_v, void **data, float UNUS
PTCACHE_DATA_TO(data, BPHYS_DATA_XCONST, 0, vert->xconst);
}
}
-static void ptcache_cloth_interpolate(int index, void *cloth_v, void **data, float UNUSED(frs_sec), 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, float *old_data)
{
ClothModifierData *clmd= cloth_v;
Cloth *cloth= clmd->clothObject;
@@ -455,106 +467,6 @@ static int ptcache_cloth_totpoint(void *cloth_v, int UNUSED(cfra))
}
/* Smoke functions */
-static int ptcache_compress_write(PTCacheFile *pf, unsigned char *in, unsigned int in_len, unsigned char *out, int mode)
-{
- int r = 0;
- unsigned char compressed = 0;
- unsigned int out_len= 0;
- unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
- size_t sizeOfIt = 5;
-
- (void)mode; /* unused when building w/o compression */
-
-#ifdef WITH_LZO
- out_len= LZO_OUT_LEN(in_len);
- if(mode == 1) {
- LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS);
-
- r = lzo1x_1_compress(in, (lzo_uint)in_len, out, (lzo_uint *)&out_len, wrkmem);
- if (!(r == LZO_E_OK) || (out_len >= in_len))
- compressed = 0;
- else
- compressed = 1;
- }
-#endif
-#ifdef WITH_LZMA
- if(mode == 2) {
-
- r = LzmaCompress(out, (size_t *)&out_len, in, in_len,//assume sizeof(char)==1....
- props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2);
-
- if(!(r == SZ_OK) || (out_len >= in_len))
- compressed = 0;
- else
- compressed = 2;
- }
-#endif
-
- ptcache_file_write(pf, &compressed, 1, sizeof(unsigned char));
- if(compressed) {
- ptcache_file_write(pf, &out_len, 1, sizeof(unsigned int));
- ptcache_file_write(pf, out, out_len, sizeof(unsigned char));
- }
- else
- ptcache_file_write(pf, in, in_len, sizeof(unsigned char));
-
- if(compressed == 2)
- {
- ptcache_file_write(pf, &sizeOfIt, 1, sizeof(unsigned int));
- ptcache_file_write(pf, props, sizeOfIt, sizeof(unsigned char));
- }
-
- MEM_freeN(props);
-
- return r;
-}
-
-static int ptcache_compress_read(PTCacheFile *pf, unsigned char *result, unsigned int len)
-{
- int r = 0;
- unsigned char compressed = 0;
- unsigned int in_len;
-#ifdef WITH_LZO
- unsigned int out_len = len;
- size_t sizeOfIt = 5;
-#endif
- unsigned char *in;
- unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
-
- ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
- if(compressed) {
- ptcache_file_read(pf, &in_len, 1, sizeof(unsigned int));
- if(in_len==0) {
- /* do nothing */
- }
- else {
- in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer");
- ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
-#ifdef WITH_LZO
- if(compressed == 1)
- r = lzo1x_decompress_safe(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
-#endif
-#ifdef WITH_LZMA
- if(compressed == 2)
- {
- size_t leni = in_len, leno = out_len;
- ptcache_file_read(pf, &sizeOfIt, 1, sizeof(unsigned int));
- ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
- r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
- }
-#endif
- MEM_freeN(in);
- }
- }
- else {
- ptcache_file_read(pf, result, len, sizeof(unsigned char));
- }
-
- MEM_freeN(props);
-
- return r;
-}
-
static int ptcache_smoke_totpoint(void *smoke_v, int UNUSED(cfra))
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
@@ -566,8 +478,6 @@ static int ptcache_smoke_totpoint(void *smoke_v, int UNUSED(cfra))
else
return 0;
}
-
-
static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
@@ -586,18 +496,18 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v)
smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles);
- ptcache_compress_write(pf, (unsigned char *)sds->shadow, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)dens, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)densold, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)heat, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)heatold, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)vx, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)vy, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)vz, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)vxold, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)vyold, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)vzold, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)obstacles, (unsigned int)res, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)sds->shadow, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)heat, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)heatold, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)vx, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)vy, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)vz, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)vxold, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)vyold, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)vzold, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)obstacles, (unsigned int)res, out, mode);
ptcache_file_write(pf, &dt, 1, sizeof(float));
ptcache_file_write(pf, &dx, 1, sizeof(float));
@@ -627,14 +537,14 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v)
smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len_big), "pointcache_lzo_buffer");
- ptcache_compress_write(pf, (unsigned char *)dens, in_len_big, out, mode);
- ptcache_compress_write(pf, (unsigned char *)densold, in_len_big, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len_big, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len_big, out, mode);
MEM_freeN(out);
out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
- ptcache_compress_write(pf, (unsigned char *)tcu, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)tcv, in_len, out, mode);
- ptcache_compress_write(pf, (unsigned char *)tcw, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)tcu, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)tcv, in_len, out, mode);
+ ptcache_file_compressed_write(pf, (unsigned char *)tcw, in_len, out, mode);
MEM_freeN(out);
ret = 1;
@@ -642,9 +552,6 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v)
return ret;
}
-
-
-
static void ptcache_smoke_read(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
@@ -658,18 +565,18 @@ static void ptcache_smoke_read(PTCacheFile *pf, void *smoke_v)
smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles);
- ptcache_compress_read(pf, (unsigned char *)sds->shadow, out_len);
- ptcache_compress_read(pf, (unsigned char*)dens, out_len);
- ptcache_compress_read(pf, (unsigned char*)densold, out_len);
- ptcache_compress_read(pf, (unsigned char*)heat, out_len);
- ptcache_compress_read(pf, (unsigned char*)heatold, out_len);
- ptcache_compress_read(pf, (unsigned char*)vx, out_len);
- ptcache_compress_read(pf, (unsigned char*)vy, out_len);
- ptcache_compress_read(pf, (unsigned char*)vz, out_len);
- ptcache_compress_read(pf, (unsigned char*)vxold, out_len);
- ptcache_compress_read(pf, (unsigned char*)vyold, out_len);
- ptcache_compress_read(pf, (unsigned char*)vzold, out_len);
- ptcache_compress_read(pf, (unsigned char*)obstacles, (unsigned int)res);
+ ptcache_file_compressed_read(pf, (unsigned char *)sds->shadow, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)heat, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)heatold, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)vx, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)vy, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)vz, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)vxold, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)vyold, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)vzold, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)obstacles, (unsigned int)res);
ptcache_file_read(pf, &dt, 1, sizeof(float));
ptcache_file_read(pf, &dx, 1, sizeof(float));
@@ -686,12 +593,12 @@ static void ptcache_smoke_read(PTCacheFile *pf, void *smoke_v)
smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
- ptcache_compress_read(pf, (unsigned char*)dens, out_len_big);
- ptcache_compress_read(pf, (unsigned char*)densold, out_len_big);
+ ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len_big);
+ ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len_big);
- ptcache_compress_read(pf, (unsigned char*)tcu, out_len);
- ptcache_compress_read(pf, (unsigned char*)tcv, out_len);
- ptcache_compress_read(pf, (unsigned char*)tcw, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)tcu, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)tcv, out_len);
+ ptcache_file_compressed_read(pf, (unsigned char*)tcw, out_len);
}
}
}
@@ -709,21 +616,25 @@ void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
pid->ptcaches= &sb->ptcaches;
pid->totpoint= pid->totwrite= ptcache_softbody_totpoint;
- pid->write_elem= ptcache_softbody_write;
- pid->write_stream = NULL;
- pid->read_stream = NULL;
- pid->read_elem= ptcache_softbody_read;
- pid->interpolate_elem= ptcache_softbody_interpolate;
+ pid->write_point = ptcache_softbody_write;
+ pid->read_point = ptcache_softbody_read;
+ pid->interpolate_point = ptcache_softbody_interpolate;
+
+ pid->write_stream = NULL;
+ pid->read_stream = NULL;
- pid->write_header= ptcache_basic_header_write;
- pid->read_header= ptcache_basic_header_read;
+ pid->write_extra_data = NULL;
+ pid->read_extra_data = NULL;
+ pid->interpolate_extra_data = NULL;
+
+ pid->write_header = ptcache_basic_header_write;
+ pid->read_header = ptcache_basic_header_read;
pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY);
pid->info_types= 0;
pid->stack_index = pid->cache->index;
}
-
void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *psys)
{
memset(pid, 0, sizeof(PTCacheID));
@@ -739,19 +650,24 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
if(psys->part->type != PART_HAIR)
pid->flag |= PTCACHE_VEL_PER_SEC;
- pid->write_elem= ptcache_particle_write;
- pid->write_stream = NULL;
- pid->read_stream = NULL;
- pid->read_elem= ptcache_particle_read;
- pid->interpolate_elem= ptcache_particle_interpolate;
+ pid->totpoint = ptcache_particle_totpoint;
+ pid->totwrite = ptcache_particle_totwrite;
+
+ pid->write_point = ptcache_particle_write;
+ pid->read_point = ptcache_particle_read;
+ pid->interpolate_point = ptcache_particle_interpolate;
- pid->totpoint= ptcache_particle_totpoint;
- pid->totwrite= ptcache_particle_totwrite;
+ pid->write_stream = NULL;
+ pid->read_stream = NULL;
- pid->write_header= ptcache_basic_header_write;
- pid->read_header= ptcache_basic_header_read;
+ pid->write_extra_data = NULL;
+ pid->read_extra_data = NULL;
+ pid->interpolate_extra_data = NULL;
- pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY) | (1<<BPHYS_DATA_INDEX);
+ pid->write_header = ptcache_basic_header_write;
+ pid->read_header = ptcache_basic_header_read;
+
+ pid->data_types = (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY) | (1<<BPHYS_DATA_INDEX);
if(psys->part->phystype == PART_PHYS_BOIDS)
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION) | (1<<BPHYS_DATA_BOIDS);
@@ -765,7 +681,6 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
pid->info_types= (1<<BPHYS_DATA_TIMES);
}
-
void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *clmd)
{
memset(pid, 0, sizeof(PTCacheID));
@@ -779,19 +694,23 @@ void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *cl
pid->ptcaches= &clmd->ptcaches;
pid->totpoint= pid->totwrite= ptcache_cloth_totpoint;
- pid->write_elem= ptcache_cloth_write;
- pid->write_stream = NULL;
- pid->read_stream = NULL;
- pid->read_elem= ptcache_cloth_read;
- pid->interpolate_elem= ptcache_cloth_interpolate;
+ pid->write_point = ptcache_cloth_write;
+ pid->read_point = ptcache_cloth_read;
+ pid->interpolate_point = ptcache_cloth_interpolate;
- pid->write_header= ptcache_basic_header_write;
- pid->read_header= ptcache_basic_header_read;
+ pid->write_stream = NULL;
+ pid->read_stream = NULL;
+
+ pid->write_extra_data = NULL;
+ pid->read_extra_data = NULL;
+ pid->interpolate_extra_data = NULL;
+
+ pid->write_header = ptcache_basic_header_write;
+ pid->read_header = ptcache_basic_header_read;
pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY) | (1<<BPHYS_DATA_XCONST);
pid->info_types= 0;
}
-
void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd)
{
SmokeDomainSettings *sds = smd->domain;
@@ -810,16 +729,19 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo
pid->totpoint= pid->totwrite= ptcache_smoke_totpoint;
- pid->write_elem= NULL;
- pid->read_elem= NULL;
+ pid->write_point = NULL;
+ pid->read_point = NULL;
+ pid->interpolate_point = NULL;
- pid->read_stream = ptcache_smoke_read;
- pid->write_stream = ptcache_smoke_write;
-
- pid->interpolate_elem= NULL;
+ pid->read_stream = ptcache_smoke_read;
+ pid->write_stream = ptcache_smoke_write;
- pid->write_header= ptcache_basic_header_write;
- pid->read_header= ptcache_basic_header_read;
+ pid->write_extra_data = NULL;
+ pid->read_extra_data = NULL;
+ pid->interpolate_extra_data = NULL;
+
+ pid->write_header = ptcache_basic_header_write;
+ pid->read_header = ptcache_basic_header_read;
pid->data_types= 0;
pid->info_types= 0;
@@ -829,7 +751,6 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo
if(sds->wt)
pid->data_types |= (1<<BPHYS_DATA_SMOKE_HIGH);
}
-
void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis)
{
PTCacheID *pid;
@@ -901,7 +822,6 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
}
}
-
/* File handling */
/* Takes an Object ID and returns a unique name
@@ -1035,21 +955,125 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
pf= MEM_mallocN(sizeof(PTCacheFile), "PTCacheFile");
pf->fp= fp;
pf->old_format = 0;
+ pf->frame = cfra;
return pf;
}
-
static void ptcache_file_close(PTCacheFile *pf)
{
- fclose(pf->fp);
- MEM_freeN(pf);
+ if(pf) {
+ fclose(pf->fp);
+ MEM_freeN(pf);
+ }
+}
+
+static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result, size_t len)
+{
+ int r = 0;
+ unsigned char compressed = 0;
+ size_t in_len;
+#ifdef WITH_LZO
+ size_t out_len = len;
+ size_t sizeOfIt = 5;
+#endif
+ unsigned char *in;
+ unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+
+ ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
+ if(compressed) {
+ uint32_t size;
+ ptcache_file_read(pf, &size, 1, sizeof(uint32_t));
+ in_len = (size_t)size;
+ if(in_len==0) {
+ /* do nothing */
+ }
+ else {
+ in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer");
+ ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
+#ifdef WITH_LZO
+ if(compressed == 1)
+ r = lzo1x_decompress_safe(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
+#endif
+#ifdef WITH_LZMA
+ if(compressed == 2)
+ {
+ size_t leni = in_len, leno = out_len;
+ ptcache_file_read(pf, &size, 1, sizeof(unsigned int));
+ sizeOfIt = (size_t)size;
+ ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
+ r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
+ }
+#endif
+ MEM_freeN(in);
+ }
+ }
+ else {
+ ptcache_file_read(pf, result, len, sizeof(unsigned char));
+ }
+
+ MEM_freeN(props);
+
+ return r;
}
+static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, size_t in_len, unsigned char *out, int mode)
+{
+ int r = 0;
+ unsigned char compressed = 0;
+ size_t out_len= 0;
+ unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+ size_t sizeOfIt = 5;
-static int ptcache_file_read(PTCacheFile *pf, void *f, size_t tot, int size)
+ (void)mode; /* unused when building w/o compression */
+
+#ifdef WITH_LZO
+ out_len= LZO_OUT_LEN(in_len);
+ if(mode == 1) {
+ LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS);
+
+ r = lzo1x_1_compress(in, (lzo_uint)in_len, out, (lzo_uint *)&out_len, wrkmem);
+ if (!(r == LZO_E_OK) || (out_len >= in_len))
+ compressed = 0;
+ else
+ compressed = 1;
+ }
+#endif
+#ifdef WITH_LZMA
+ if(mode == 2) {
+
+ r = LzmaCompress(out, (size_t *)&out_len, in, in_len,//assume sizeof(char)==1....
+ props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2);
+
+ if(!(r == SZ_OK) || (out_len >= in_len))
+ compressed = 0;
+ else
+ compressed = 2;
+ }
+#endif
+
+ ptcache_file_write(pf, &compressed, 1, sizeof(unsigned char));
+ if(compressed) {
+ uint32_t size = (uint32_t) out_len;
+ ptcache_file_write(pf, &size, 1, sizeof(uint32_t));
+ ptcache_file_write(pf, out, out_len, sizeof(unsigned char));
+ }
+ else
+ ptcache_file_write(pf, in, in_len, sizeof(unsigned char));
+
+ if(compressed == 2)
+ {
+ ptcache_file_write(pf, &sizeOfIt, 1, sizeof(uint32_t));
+ ptcache_file_write(pf, props, sizeOfIt, sizeof(unsigned char));
+ }
+
+ MEM_freeN(props);
+
+ return r;
+}
+static int ptcache_file_read(PTCacheFile *pf, void *f, size_t tot, size_t size)
{
return (fread(f, size, tot, pf->fp) == tot);
}
-static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, int size)
+static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, size_t size)
{
return (fwrite(f, size, tot, pf->fp) == tot);
}
@@ -1077,6 +1101,7 @@ static int ptcache_file_data_write(PTCacheFile *pf)
}
static int ptcache_file_header_begin_read(PTCacheFile *pf)
{
+ uint32_t typeflag=0;
int error=0;
char bphysics[8];
@@ -1088,8 +1113,11 @@ static int ptcache_file_header_begin_read(PTCacheFile *pf)
if(!error && strncmp(bphysics, "BPHYSICS", 8))
error = 1;
- if(!error && !fread(&pf->type, sizeof(int), 1, pf->fp))
+ if(!error && !fread(&typeflag, sizeof(uint32_t), 1, pf->fp))
error = 1;
+
+ pf->type = (typeflag & PTCACHE_TYPEFLAG_TYPEMASK);
+ pf->flag = (typeflag & PTCACHE_TYPEFLAG_FLAGMASK);
/* if there was an error set file as it was */
if(error)
@@ -1097,22 +1125,20 @@ static int ptcache_file_header_begin_read(PTCacheFile *pf)
return !error;
}
-
-
static int ptcache_file_header_begin_write(PTCacheFile *pf)
{
const char *bphysics = "BPHYSICS";
+ uint32_t typeflag = pf->type + pf->flag;
if(fwrite(bphysics, sizeof(char), 8, pf->fp) != 8)
return 0;
- if(!fwrite(&pf->type, sizeof(int), 1, pf->fp))
+ if(!fwrite(&typeflag, sizeof(uint32_t), 1, pf->fp))
return 0;
return 1;
}
-
/* Data pointer handling */
int BKE_ptcache_data_size(int data_type)
{
@@ -1133,38 +1159,6 @@ static void ptcache_file_pointers_init(PTCacheFile *pf)
pf->cur[BPHYS_DATA_BOIDS] = (data_types & (1<<BPHYS_DATA_BOIDS)) ? &pf->data.boids : NULL;
}
-static void ptcache_file_pointers_seek(int index, PTCacheFile *pf)
-{
- int i, size=0;
- int data_types = pf->data_types;
-
- if(data_types & (1<<BPHYS_DATA_INDEX)) {
- int totpoint;
- /* The simplest solution is to just write to the very end. This may cause
- * some data duplication, but since it's on disk it's not so bad. The correct
- * thing would be to search through the file for the correct index and only
- * write to the end if it's not found, but this could be quite slow.
- */
- fseek(pf->fp, 8 + sizeof(int), SEEK_SET);
- fread(&totpoint, sizeof(int), 1, pf->fp);
-
- totpoint++;
-
- fseek(pf->fp, 8 + sizeof(int), SEEK_SET);
- fwrite(&totpoint, sizeof(int), 1, pf->fp);
-
- fseek(pf->fp, 0, SEEK_END);
- }
- else {
- for(i=0; i<BPHYS_TOT_DATA; i++)
- size += (pf->data_types & (1<<i)) ? ptcache_data_size[i] : 0;
-
- /* size of default header + data up to index */
- fseek(pf->fp, 8 + 3*sizeof(int) + index * size, SEEK_SET);
- }
-
- ptcache_file_pointers_init(pf);
-}
void BKE_ptcache_mem_pointers_init(PTCacheMem *pm)
{
int data_types = pm->data_types;
@@ -1239,8 +1233,15 @@ static void ptcache_data_copy(void *from[], void *to[])
}
}
+static void ptcache_extra_free(PTCacheMem *pm)
+{
+ PTCacheExtra *extra = pm->extradata.first;
-
+ for(; extra; extra=extra->next) {
+ if(extra->data)
+ MEM_freeN(extra->data);
+ }
+}
static int ptcache_old_elemsize(PTCacheID *pid)
{
if(pid->type==PTCACHE_TYPE_SOFTBODY)
@@ -1253,57 +1254,33 @@ static int ptcache_old_elemsize(PTCacheID *pid)
return 0;
}
-static void *ptcache_find_frame(PTCacheID *pid, int frame)
-{
- if(pid->cache->flag & PTCACHE_DISK_CACHE) {
- PTCacheFile *pf = ptcache_file_open(pid, PTCACHE_FILE_READ, frame);
- if(pf)
- pf->frame = frame;
- return pf;
- }
- else {
- PTCacheMem *pm = pid->cache->mem_cache.first;
- for(; pm; pm=pm->next) {
- if(pm->frame == frame)
- break;
- }
- return (void*)pm;
- }
-}
-
-static void ptcache_find_frames_around(PTCacheID *pid, int frame, void **cache1, void **cache2)
+static void ptcache_find_frames_around(PTCacheID *pid, int frame, int *fra1, int *fra2)
{
- int cfra1=frame, cfra2=frame;
-
if(pid->cache->flag & PTCACHE_DISK_CACHE) {
- PTCacheFile *pf=NULL;
- PTCacheFile *pf2=NULL;
+ int cfra1=frame-1, cfra2=frame+1;
- while(cfra1 >= pid->cache->startframe && pf==NULL) {
+ while(cfra1 >= pid->cache->startframe && !BKE_ptcache_id_exist(pid, cfra1))
cfra1--;
- pf= ptcache_file_open(pid, PTCACHE_FILE_READ, cfra1);
- }
- if(pf)
- pf->frame = cfra1;
+ if(cfra1 < pid->cache->startframe)
+ cfra1 = 0;
- while(cfra2 < pid->cache->endframe && !pf2) {
+ while(cfra2 <= pid->cache->endframe && !BKE_ptcache_id_exist(pid, cfra2))
cfra2++;
- pf2= ptcache_file_open(pid, PTCACHE_FILE_READ, cfra2);
- }
- if(pf2)
- pf2->frame = cfra2;
+ if(cfra2 > pid->cache->endframe)
+ cfra2 = 0;
- if(pf && !pf2) {
- pf2 = pf;
- pf = NULL;
+ if(cfra1 && !cfra2) {
+ *fra1 = 0;
+ *fra2 = cfra1;
+ }
+ else {
+ *fra1 = cfra1;
+ *fra2 = cfra2;
}
-
- *cache1 = (void*)pf;
- *cache2 = (void*)pf2;
}
- else if(pid->cache->mem_cache.first){
+ else if(pid->cache->mem_cache.first) {
PTCacheMem *pm = pid->cache->mem_cache.first;
PTCacheMem *pm2 = pid->cache->mem_cache.last;
@@ -1318,135 +1295,340 @@ static void ptcache_find_frames_around(PTCacheID *pid, int frame, void **cache1,
}
if(pm && !pm2) {
- pm2 = pm;
- pm = NULL;
+ *fra1 = 0;
+ *fra2 = pm->frame;
}
+ else {
+ *fra1 = pm->frame;
+ *fra2 = pm2->frame;
+ }
+ }
+}
+static void ptcache_make_index_array(PTCacheMem *pm, int totpoint)
+{
+ int i, *index;
- *cache1 = (void*)pm;
- *cache2 = (void*)pm2;
+ if(pm->index_array) {
+ MEM_freeN(pm->index_array);
+ pm->index_array = NULL;
}
+
+ if(!pm->data[BPHYS_DATA_INDEX])
+ return;
+
+ pm->index_array = MEM_callocN(totpoint * sizeof(int), "PTCacheMem index_array");
+ index = pm->data[BPHYS_DATA_INDEX];
+
+ for(i=0; i<pm->totpoint; i++, index++)
+ pm->index_array[*index] = i + 1;
}
-static int ptcache_read_init(PTCacheID *pid, void **cache, int *totpoint)
+
+static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra)
{
- if(*cache==NULL)
+ PTCacheFile *pf = ptcache_file_open(pid, PTCACHE_FILE_READ, cfra);
+ PTCacheMem *pm = NULL;
+ int i, error = 0;
+
+ if(pf == NULL)
return 0;
- if(pid->cache->flag & PTCACHE_DISK_CACHE) {
- PTCacheFile *pf = (PTCacheFile *)(*cache);
+ if(!ptcache_file_header_begin_read(pf))
+ error = 1;
- if(ptcache_file_header_begin_read(pf)) {
- if(pf->type != pid->type) {
- /* todo report error */
- ptcache_file_close(pf);
- *cache = NULL;
- return 0;
- }
- else if(pid->read_header(pf)) {
- ptcache_file_pointers_init(pf);
- *totpoint = pf->totpoint;
+ if(!error && (pf->type != pid->type || !pid->read_header(pf)))
+ error = 1;
+
+ if(!error) {
+ pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
+
+ pm->totpoint = pf->totpoint;
+ pm->data_types = pf->data_types;
+ pm->frame = pf->frame;
+
+ ptcache_data_alloc(pm);
+
+ if(pf->flag & PTCACHE_TYPEFLAG_COMPRESS) {
+ for(i=0; i<BPHYS_TOT_DATA; i++) {
+ unsigned int out_len = pm->totpoint*ptcache_data_size[i];
+ if(pf->data_types & (1<<i))
+ ptcache_file_compressed_read(pf, (unsigned char*)(pm->data[i]), out_len);
}
}
else {
- /* fall back to old cache file format */
- pf->old_format = 1;
- *totpoint = pid->totpoint(pid->calldata, (int) pf->frame);
+ BKE_ptcache_mem_pointers_init(pm);
+ ptcache_file_pointers_init(pf);
+
+ for(i=0; i<pm->totpoint; i++) {
+ if(!ptcache_file_data_read(pf)) {
+ error = 1;
+ break;
+ }
+ ptcache_data_copy(pf->cur, pm->cur);
+ BKE_ptcache_mem_pointers_incr(pm);
+ }
}
- return pf->frame;
}
- else {
- PTCacheMem *pm = (PTCacheMem *)(*cache);
- BKE_ptcache_mem_pointers_init(pm);
- *totpoint = pm->totpoint;
- return pm->frame;
+ if(!error && pf->flag & PTCACHE_TYPEFLAG_EXTRADATA) {
+ uint32_t extratype = 0;
+ uint32_t value;
+
+ while(ptcache_file_read(pf, &extratype, 1, sizeof(uint32_t))) {
+ PTCacheExtra *extra = MEM_callocN(sizeof(PTCacheExtra), "Pointcache extradata");
+
+ extra->type = extratype;
+
+ ptcache_file_read(pf, &value, 1, sizeof(uint32_t));
+ extra->flag = value;
+ ptcache_file_read(pf, &value, 1, sizeof(uint32_t));
+ extra->totdata = value;
+ ptcache_file_read(pf, &value, 1, sizeof(uint32_t));
+ extra->datasize = value;
+
+ extra->data = MEM_callocN(extra->totdata * extra->datasize, "Pointcache extradata->data");
+
+ if(pf->flag & PTCACHE_TYPEFLAG_COMPRESS)
+ ptcache_file_compressed_read(pf, (unsigned char*)(extra->data), extra->totdata*extra->datasize);
+ else
+ ptcache_file_read(pf, extra->data, extra->totdata, extra->datasize);
+
+ BLI_addtail(&pm->extradata, extra);
+ }
+ }
+
+ if(!error)
+ ptcache_make_index_array(pm, pid->totpoint(pid->calldata, pm->frame));
+
+ if(error && pm) {
+ ptcache_data_free(pm);
+ ptcache_extra_free(pm);
+ MEM_freeN(pm);
+ pm = NULL;
}
+
+ ptcache_file_close(pf);
+
+ if (error && G.f & G_DEBUG)
+ printf("Error reading from disk cache\n");
+
+ return pm;
}
-static int ptcache_read(PTCacheID *pid, void *cache, int totpoint, float frs_sec)
+static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
{
- int i;
- int *index = &i;
+ PTCacheFile *pf = NULL;
+ int i, error = 0;
+
+ BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_FRAME, pm->frame);
- if(pid->cache->flag & PTCACHE_DISK_CACHE) {
- PTCacheFile *pf = (PTCacheFile *)cache;
- if(pf->old_format) {
- int old_elemsize = ptcache_old_elemsize(pid);
- float old_data[14];
+ pf = ptcache_file_open(pid, PTCACHE_FILE_WRITE, pm->frame);
- for(i=0; i<totpoint; i++) {
- if(ptcache_file_read(pf, (void*)old_data, 1, old_elemsize))
- pid->read_elem(i, pid->calldata, NULL, frs_sec, (float)pf->frame, old_data);
- else
- return 0;
+ if(pf==NULL) {
+ if (G.f & G_DEBUG)
+ printf("Error opening disk cache file for writing\n");
+ return 0;
+ }
+
+ pf->data_types = pm->data_types;
+ pf->totpoint = pm->totpoint;
+ pf->type = pid->type;
+ pf->flag = 0;
+
+ if(pm->extradata.first)
+ pf->flag |= PTCACHE_TYPEFLAG_EXTRADATA;
+
+ if(pid->cache->compression)
+ pf->flag |= PTCACHE_TYPEFLAG_COMPRESS;
+
+ if(!ptcache_file_header_begin_write(pf) || !pid->write_header(pf))
+ error = 1;
+
+ if(!error) {
+ if(pid->cache->compression) {
+ for(i=0; i<BPHYS_TOT_DATA; i++) {
+ if(pm->data[i]) {
+ unsigned int in_len = pm->totpoint*ptcache_data_size[i];
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ ptcache_file_compressed_write(pf, (unsigned char*)(pm->data[i]), in_len, out, pid->cache->compression);
+ MEM_freeN(out);
+ }
}
}
else {
- if(pf->data_types & (1<<BPHYS_DATA_INDEX))
- index = &pf->data.index;
-
- for(i=0; i<totpoint; i++) {
- if(ptcache_file_data_read(pf))
- pid->read_elem(*index, pid->calldata, pf->cur, frs_sec, (float)pf->frame, NULL);
- else
- return 0;
+ BKE_ptcache_mem_pointers_init(pm);
+ ptcache_file_pointers_init(pf);
+
+ for(i=0; i<pm->totpoint; i++) {
+ ptcache_data_copy(pm->cur, pf->cur);
+ if(!ptcache_file_data_write(pf)) {
+ error = 1;
+ break;
+ }
+ BKE_ptcache_mem_pointers_incr(pm);
}
}
}
+
+ if(!error && pm->extradata.first) {
+ PTCacheExtra *extra = pm->extradata.first;
+ uint32_t value;
+
+ for(; extra; extra=extra->next) {
+ if(extra->data == NULL || extra->totdata == 0)
+ continue;
+
+ value = extra->type;
+ ptcache_file_write(pf, &value, 1, sizeof(uint32_t));
+ value = extra->flag;
+ ptcache_file_write(pf, &value, 1, sizeof(uint32_t));
+ value = extra->totdata;
+ ptcache_file_write(pf, &value, 1, sizeof(uint32_t));
+ value = extra->datasize;
+ ptcache_file_write(pf, &value, 1, sizeof(uint32_t));
+
+ if(pid->cache->compression) {
+ unsigned int in_len = extra->totdata * extra->datasize;
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ ptcache_file_compressed_write(pf, (unsigned char*)(extra->data), in_len, out, pid->cache->compression);
+ MEM_freeN(out);
+ }
+ else {
+ ptcache_file_write(pf, extra->data, extra->totdata, extra->datasize);
+ }
+ }
+ }
+
+ ptcache_file_close(pf);
+
+ if (error && G.f & G_DEBUG)
+ printf("Error writing to disk cache\n");
+
+ return error==0;
+}
+
+static int ptcache_read_stream(PTCacheID *pid, int cfra)
+{
+ PTCacheFile *pf = ptcache_file_open(pid, PTCACHE_FILE_READ, cfra);
+ int error = 0;
+
+ if(pid->read_stream == NULL)
+ return 0;
+
+ if(pf == NULL) {
+ if (G.f & G_DEBUG)
+ printf("Error opening disk cache file for reading\n");
+ return 0;
+ }
+
+ if(!ptcache_file_header_begin_read(pf))
+ error = 1;
+
+ if(!error && (pf->type != pid->type || !pid->read_header(pf)))
+ error = 1;
+
+ if(!error && pf->totpoint != pid->totpoint(pid->calldata, cfra))
+ error = 1;
+
+ if(!error) {
+ ptcache_file_pointers_init(pf);
+
+ // we have stream reading here
+ pid->read_stream(pf, pid->calldata);
+ }
+
+ ptcache_file_close(pf);
+
+ return error == 0;
+}
+static int ptcache_read(PTCacheID *pid, int cfra)
+{
+ PTCacheMem *pm = NULL;
+ int i;
+ int *index = &i;
+
+ /* get a memory cache to read from */
+ if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+ pm = ptcache_disk_frame_to_mem(pid, cfra);
+ }
else {
- PTCacheMem *pm = (PTCacheMem *)cache;
+ pm = pid->cache->mem_cache.first;
+
+ while(pm && pm->frame != cfra)
+ pm = pm->next;
+ }
+
+ /* read the cache */
+ if(pm) {
+ int totpoint = pm->totpoint;
+
+ if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
+ totpoint = MIN2(totpoint, pid->totpoint(pid->calldata, cfra));
+
+ BKE_ptcache_mem_pointers_init(pm);
for(i=0; i<totpoint; i++) {
if(pm->data_types & (1<<BPHYS_DATA_INDEX))
index = pm->cur[BPHYS_DATA_INDEX];
- pid->read_elem(*index, pid->calldata, pm->cur, frs_sec, (float)pm->frame, NULL);
+ pid->read_point(*index, pid->calldata, pm->cur, (float)pm->frame, NULL);
BKE_ptcache_mem_pointers_incr(pm);
}
+
+ if(pid->read_extra_data && pm->extradata.first)
+ pid->read_extra_data(pid->calldata, pm, (float)pm->frame);
+
+ /* clean up temporary memory cache */
+ if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+ ptcache_data_free(pm);
+ ptcache_extra_free(pm);
+ MEM_freeN(pm);
+ }
}
return 1;
}
-static int ptcache_interpolate(PTCacheID *pid, void *cache1, void *cache2, int totpoint, float cfra, float frs_sec)
+static int ptcache_interpolate(PTCacheID *pid, float cfra, int cfra1, int cfra2)
{
+ PTCacheMem *pm = NULL;
int i;
int *index = &i;
+ /* get a memory cache to read from */
if(pid->cache->flag & PTCACHE_DISK_CACHE) {
- PTCacheFile *pf1 = (PTCacheFile *)cache1;
- PTCacheFile *pf2 = (PTCacheFile *)cache2;
- if(pf2->old_format) {
- int old_elemsize = ptcache_old_elemsize(pid);
- float old_data[14];
-
- for(i=0; i<totpoint; i++) {
- if(ptcache_file_read(pf2, (void*)old_data, 1, old_elemsize))
- pid->interpolate_elem(i, pid->calldata, NULL, frs_sec, cfra, (float)pf1->frame, (float)pf2->frame, old_data);
- else
- return 0;
- }
- }
- else {
- if(pf2->data_types & (1<<BPHYS_DATA_INDEX))
- index = &pf2->data.index;
-
- for(i=0; i<totpoint; i++) {
- if(ptcache_file_data_read(pf2))
- pid->interpolate_elem(*index, pid->calldata, pf2->cur, frs_sec, cfra, (float)pf1->frame, (float)pf2->frame, NULL);
- else
- return 0;
- }
- }
+ pm = ptcache_disk_frame_to_mem(pid, cfra2);
}
else {
- PTCacheMem *pm1 = (PTCacheMem *)cache1;
- PTCacheMem *pm2 = (PTCacheMem *)cache2;
+ pm = pid->cache->mem_cache.first;
+
+ while(pm && pm->frame != cfra2)
+ pm = pm->next;
+ }
+
+ /* read the cache */
+ if(pm) {
+ int totpoint = pm->totpoint;
+
+ if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
+ totpoint = MIN2(totpoint, pid->totpoint(pid->calldata, (int)cfra));
+
+ BKE_ptcache_mem_pointers_init(pm);
for(i=0; i<totpoint; i++) {
- if(pm2->data_types & (1<<BPHYS_DATA_INDEX))
- index = pm2->cur[BPHYS_DATA_INDEX];
+ if(pm->data_types & (1<<BPHYS_DATA_INDEX))
+ index = pm->cur[BPHYS_DATA_INDEX];
- pid->interpolate_elem(*index, pid->calldata, pm2->cur, frs_sec, cfra, (float)pm1->frame, (float)pm2->frame, NULL);
- BKE_ptcache_mem_pointers_incr(pm2);
+ pid->interpolate_point(*index, pid->calldata, pm->cur, cfra, (float)cfra1, (float)cfra2, NULL);
+ BKE_ptcache_mem_pointers_incr(pm);
+ }
+
+ if(pid->interpolate_extra_data && pm->extradata.first)
+ pid->interpolate_extra_data(pid->calldata, pm, cfra, (float)cfra1, (float)cfra2);
+
+ /* clean up temporary memory cache */
+ if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+ ptcache_data_free(pm);
+ ptcache_extra_free(pm);
+ MEM_freeN(pm);
}
}
@@ -1454,11 +1636,9 @@ static int ptcache_interpolate(PTCacheID *pid, void *cache1, void *cache2, int t
}
/* reads cache from disk or memory */
/* possible to get old or interpolated result */
-int BKE_ptcache_read(PTCacheID *pid, float cfra, float frs_sec)
+int BKE_ptcache_read(PTCacheID *pid, float cfra)
{
- void *cache1=NULL, *cache2=NULL;
int cfrai = (int)cfra, cfra1=0, cfra2=0;
- int totpoint = 0, totpoint2 = 0;
int ret = 0;
/* nothing to read to */
@@ -1467,88 +1647,49 @@ int BKE_ptcache_read(PTCacheID *pid, float cfra, float frs_sec)
if(pid->cache->flag & PTCACHE_READ_INFO) {
pid->cache->flag &= ~PTCACHE_READ_INFO;
- BKE_ptcache_read(pid, 0, frs_sec);
+ ptcache_read(pid, 0);
}
/* first check if we have the actual frame cached */
- if(cfra == (float)cfrai)
- cache1 = ptcache_find_frame(pid, cfrai);
+ if(cfra == (float)cfrai && BKE_ptcache_id_exist(pid, cfrai))
+ cfra1 = cfrai;
/* no exact cache frame found so try to find cached frames around cfra */
- if(cache1==NULL)
- ptcache_find_frames_around(pid, cfrai, &cache1, &cache2);
+ if(cfra1 == 0)
+ ptcache_find_frames_around(pid, cfrai, &cfra1, &cfra2);
- if(cache1==NULL && cache2==NULL)
+ if(cfra1 == 0 && cfra2 == 0)
return 0;
- cfra1 = ptcache_read_init(pid, &cache1, &totpoint);
- cfra2 = ptcache_read_init(pid, &cache2, &totpoint2);
-
/* don't read old cache if already simulated past cached frame */
- if(!cache1 && cfra2 && cfra2 <= pid->cache->simframe)
- goto cleanup;
- if(cfra1 && cfra1==cfra2)
- goto cleanup;
-
- if(cache1) {
- if(pid->read_stream) {
- if(totpoint != pid->totpoint(pid->calldata, (int) cfra))
- goto cleanup;
- else
- {
- // we have stream reading here
- pid->read_stream((PTCacheFile *)cache1, pid->calldata);
- }
- }
- else if(pid->read_elem) {
- if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
- totpoint = MIN2(totpoint, pid->totpoint(pid->calldata, (int) cfra));
+ if(cfra1 == 0 && cfra2 && cfra2 <= pid->cache->simframe)
+ return 0;
+ if(cfra1 && cfra1 == cfra2)
+ return 0;
- if(ptcache_read(pid, cache1, totpoint, frs_sec)==0)
- goto cleanup;
- }
+ if(cfra1) {
+ if(pid->read_stream)
+ ptcache_read_stream(pid, cfra1);
+ else if(pid->read_point)
+ ptcache_read(pid, cfra1);
}
- if(cache2) {
- if(pid->read_stream) {
- if(totpoint2 != pid->totpoint(pid->calldata, (int) cfra))
- goto cleanup;
+ if(cfra2) {
+ if(pid->read_stream)
+ ptcache_read_stream(pid, cfra2);
+ else if(pid->read_point) {
+ if(cfra1 && cfra2 && pid->interpolate_point)
+ ptcache_interpolate(pid, cfra, cfra1, cfra2);
else
- {
- // we have stream reading here
- pid->read_stream((PTCacheFile *)cache2, pid->calldata);
- }
- }
- else if(pid->read_elem) {
- if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
- totpoint2 = MIN2(totpoint2, pid->totpoint(pid->calldata, (int) cfra));
-
- if(cache1 && cache2 && pid->interpolate_elem) {
- if(ptcache_interpolate(pid, cache1, cache2, totpoint2, cfra, frs_sec)==0)
- goto cleanup;
- }
- else {
- if(ptcache_read(pid, cache2, totpoint2, frs_sec)==0)
- goto cleanup;
- }
+ ptcache_read(pid, cfra2);
}
}
- if(cache1)
- ret = (cache2 ? PTCACHE_READ_INTERPOLATED : PTCACHE_READ_EXACT);
- else if(cache2) {
+ if(cfra1)
+ ret = (cfra2 ? PTCACHE_READ_INTERPOLATED : PTCACHE_READ_EXACT);
+ else if(cfra2) {
ret = PTCACHE_READ_OLD;
- pid->cache->simframe = ((pid->cache->flag & PTCACHE_DISK_CACHE) ?
- ((PTCacheFile*)cache2)->frame : ((PTCacheMem*)cache2)->frame);
- }
-
-cleanup:
-
- if(pid->cache->flag & PTCACHE_DISK_CACHE) {
- if(cache1)
- ptcache_file_close((PTCacheFile*)cache1);
- if(cache2)
- ptcache_file_close((PTCacheFile*)cache2);
+ pid->cache->simframe = cfra2;
}
if((pid->cache->flag & PTCACHE_QUICK_CACHE)==0) {
@@ -1561,31 +1702,114 @@ cleanup:
if(cfra <= pid->cache->last_exact)
pid->cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
- BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, MAX2(cfrai,pid->cache->last_exact));
+ BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, MAX2(cfrai, pid->cache->last_exact));
}
}
return ret;
}
-static void ptcache_make_index_array(PTCacheMem *pm, int totpoint)
+static int ptcache_write_stream(PTCacheID *pid, int cfra, int totpoint)
{
- int i, *index;
+ PTCacheFile *pf = NULL;
+ int error = 0;
+
+ BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_FRAME, cfra);
- if(pm->index_array) {
- MEM_freeN(pm->index_array);
- pm->index_array = NULL;
+ pf = ptcache_file_open(pid, PTCACHE_FILE_WRITE, cfra);
+
+ if(pf==NULL) {
+ if (G.f & G_DEBUG)
+ printf("Error opening disk cache file for writing\n");
+ return 0;
}
- if(!pm->data[BPHYS_DATA_INDEX])
- return;
+ pf->data_types = pid->data_types;
+ pf->totpoint = totpoint;
+ pf->type = pid->type;
+ pf->flag = 0;
- pm->index_array = MEM_callocN(totpoint * sizeof(int), "PTCacheMem index_array");
- index = pm->data[BPHYS_DATA_INDEX];
+ if(!error && (!ptcache_file_header_begin_write(pf) || !pid->write_header(pf)))
+ error = 1;
- for(i=0; i<pm->totpoint; i++, index++)
- pm->index_array[*index] = i + 1;
+ if(!error && pid->write_stream)
+ pid->write_stream(pf, pid->calldata);
+
+ ptcache_file_close(pf);
+
+ if (error && G.f & G_DEBUG)
+ printf("Error writing to disk cache\n");
+
+ return error == 0;
}
+static int ptcache_write(PTCacheID *pid, int cfra, int overwrite)
+{
+ PointCache *cache = pid->cache;
+ PTCacheMem *pm=NULL, *pm2=NULL;
+ int totpoint = pid->totpoint(pid->calldata, cfra);
+ int i, error = 0;
+
+ pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
+
+ pm->totpoint = pid->totwrite(pid->calldata, cfra);
+ pm->data_types = cfra ? pid->data_types : pid->info_types;
+
+ ptcache_data_alloc(pm);
+ BKE_ptcache_mem_pointers_init(pm);
+
+ if(overwrite) {
+ if(cache->flag & PTCACHE_DISK_CACHE) {
+ int fra = cfra-1;
+
+ while(fra >= cache->startframe && !BKE_ptcache_id_exist(pid, fra))
+ fra--;
+
+ pm2 = ptcache_disk_frame_to_mem(pid, fra);
+ }
+ else
+ pm2 = cache->mem_cache.last;
+ }
+
+ if(pid->write_point) {
+ for(i=0; i<totpoint; i++) {
+ int write = pid->write_point(i, pid->calldata, pm->cur, cfra);
+ if(write) {
+ BKE_ptcache_mem_pointers_incr(pm);
+
+ /* newly born particles have to be copied to previous cached frame */
+ if(overwrite && write == 2 && pm2 && BKE_ptcache_mem_pointers_seek(i, pm2))
+ pid->write_point(i, pid->calldata, pm2->cur, cfra);
+ }
+ }
+ }
+
+ if(pid->write_extra_data)
+ pid->write_extra_data(pid->calldata, pm, cfra);
+ pm->frame = cfra;
+
+ if(cache->flag & PTCACHE_DISK_CACHE) {
+ error += !ptcache_mem_frame_to_disk(pid, pm);
+
+ if(pm) {
+ ptcache_data_free(pm);
+ ptcache_extra_free(pm);
+ MEM_freeN(pm);
+ }
+
+ if(pm2) {
+ error += !ptcache_mem_frame_to_disk(pid, pm2);
+ ptcache_data_free(pm2);
+ ptcache_extra_free(pm2);
+ MEM_freeN(pm2);
+ }
+ }
+ else {
+ ptcache_make_index_array(pm, pid->totpoint(pid->calldata, cfra));
+ BLI_addtail(&cache->mem_cache, pm);
+ }
+
+ return error;
+}
static int ptcache_write_needed(PTCacheID *pid, int cfra, int *overwrite)
{
PointCache *cache = pid->cache;
@@ -1639,10 +1863,8 @@ static int ptcache_write_needed(PTCacheID *pid, int cfra, int *overwrite)
int BKE_ptcache_write(PTCacheID *pid, int cfra)
{
PointCache *cache = pid->cache;
- PTCacheFile *pf= NULL, *pf2= NULL;
- int i, ret = 0;
int totpoint = pid->totpoint(pid->calldata, cfra);
- int overwrite = 0;
+ int overwrite = 0, error = 0;
if(totpoint == 0 || (cfra ? pid->data_types == 0 : pid->info_types == 0))
return 0;
@@ -1650,109 +1872,29 @@ int BKE_ptcache_write(PTCacheID *pid, int cfra)
if(ptcache_write_needed(pid, cfra, &overwrite)==0)
return 0;
- if(cache->flag & PTCACHE_DISK_CACHE) {
- pf = ptcache_file_open(pid, PTCACHE_FILE_WRITE, cfra);
- if(!pf)
- goto cleanup;
-
- pf->type = pid->type;
- pf->totpoint = cfra ? pid->totwrite(pid->calldata, cfra) : totpoint;
- pf->data_types = cfra ? pid->data_types : pid->info_types;
-
- if(!ptcache_file_header_begin_write(pf) || !pid->write_header(pf))
- goto cleanup;
-
- ptcache_file_pointers_init(pf);
-
- if(pid->write_stream) {
- // we have stream writing here
- pid->write_stream(pf, pid->calldata);
- }
- else if(pid->write_elem){
- for(i=0; i<totpoint; i++) {
- int write = pid->write_elem(i, pid->calldata, pf->cur, cfra);
- if(write) {
- if(!ptcache_file_data_write(pf))
- goto cleanup;
-
- /* newly born particles have to be copied to previous cached frame */
- if(overwrite && write == 2) {
- if(!pf2) {
- /* find and initialize previous frame */
- int ofra = cfra-1;
- while(ofra > cache->startframe && !BKE_ptcache_id_exist(pid, ofra))
- ofra--;
-
- pf2 = ptcache_file_open(pid, PTCACHE_FILE_UPDATE, ofra);
- if(!pf2)
- goto cleanup;
-
- pf2->type = pid->type;
- pf2->totpoint = totpoint;
- pf2->data_types = pid->data_types;
- }
- ptcache_file_pointers_seek(i, pf2);
- pid->write_elem(i, pid->calldata, pf2->cur, cfra);
- if(!ptcache_file_data_write(pf2))
- goto cleanup;
- }
- }
- }
- }
+ if(pid->write_stream) {
+ ptcache_write_stream(pid, cfra, totpoint);
}
- else {
- PTCacheMem *pm;
- PTCacheMem *pm2;
-
- pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
-
- pm->totpoint = pid->totwrite(pid->calldata, cfra);
- pm->data_types = cfra ? pid->data_types : pid->info_types;
-
- ptcache_data_alloc(pm);
- BKE_ptcache_mem_pointers_init(pm);
-
- if(pid->write_elem) {
- for(i=0; i<totpoint; i++) {
- int write = pid->write_elem(i, pid->calldata, pm->cur, cfra);
- if(write) {
- BKE_ptcache_mem_pointers_incr(pm);
-
- /* newly born particles have to be copied to previous cached frame */
- if(overwrite && write == 2) {
- pm2 = cache->mem_cache.last;
- if(BKE_ptcache_mem_pointers_seek(i, pm2))
- pid->write_elem(i, pid->calldata, pm2->cur, cfra);
- }
- }
- }
- }
- ptcache_make_index_array(pm, pid->totpoint(pid->calldata, cfra));
-
- pm->frame = cfra;
- BLI_addtail(&cache->mem_cache, pm);
+ else if(pid->write_point) {
+ error += ptcache_write(pid, cfra, overwrite);
}
+ /* Mark frames skipped if more than 1 frame forwards since last non-skipped frame. */
if(cfra - cache->last_exact == 1 || cfra == cache->startframe) {
cache->last_exact = cfra;
cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
}
- else
+ /* Don't mark skipped when writing info file (frame 0) */
+ else if(cfra)
cache->flag |= PTCACHE_FRAMES_SKIPPED;
+ /* Update timeline cache display */
if(cache->cached_frames)
cache->cached_frames[cfra-cache->startframe] = 1;
- ret = 1;
-
-cleanup:
- if(pf) ptcache_file_close(pf);
-
- if(pf2) ptcache_file_close(pf2);
-
BKE_ptcache_update_info(pid);
- return ret;
+ return !error;
}
/* youll need to close yourself after!
* mode - PTCACHE_CLEAR_ALL,
@@ -1762,7 +1904,6 @@ cleanup:
void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
{
int len; /* store the length of the string */
- int i;
int sta, end;
/* mode is same as fopen's modes */
@@ -1810,8 +1951,6 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, path, de->d_name);
BLI_delete(path_full, 0, 0);
- if(pid->cache->cached_frames) for(i=0; i<end-sta+1; i++)
- pid->cache->cached_frames[i] = 0;
} else {
/* read the number of the file */
int frame, len2 = (int)strlen(de->d_name);
@@ -1835,6 +1974,9 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
}
}
closedir(dir);
+
+ if(mode == PTCACHE_CLEAR_ALL && pid->cache->cached_frames)
+ memset(pid->cache->cached_frames, 0, MEM_allocN_len(pid->cache->cached_frames));
}
else {
PTCacheMem *pm= pid->cache->mem_cache.first;
@@ -1845,12 +1987,14 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
if(mode == PTCACHE_CLEAR_ALL) {
/*we want startframe if the cache starts before zero*/
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
- for(; pm; pm=pm->next)
+ for(; pm; pm=pm->next) {
ptcache_data_free(pm);
+ ptcache_extra_free(pm);
+ }
BLI_freelistN(&pid->cache->mem_cache);
- if(pid->cache->cached_frames) for(i=0; i<end-sta+1; i++)
- pid->cache->cached_frames[i] = 0;
+ if(pid->cache->cached_frames)
+ memset(pid->cache->cached_frames, 0, MEM_allocN_len(pid->cache->cached_frames));
} else {
while(pm) {
if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra) ||
@@ -1859,6 +2003,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
if(pid->cache->cached_frames && pm->frame >=sta && pm->frame <= end)
pid->cache->cached_frames[pm->frame-sta] = 0;
ptcache_data_free(pm);
+ ptcache_extra_free(pm);
pm = pm->next;
BLI_freelinkN(&pid->cache->mem_cache, link);
}
@@ -1882,6 +2027,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
for(; pm; pm=pm->next) {
if(pm->frame == cfra) {
ptcache_data_free(pm);
+ ptcache_extra_free(pm);
BLI_freelinkN(&pid->cache->mem_cache, pm);
break;
}
@@ -1894,7 +2040,6 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
BKE_ptcache_update_info(pid);
}
-
int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
{
if(!pid->cache)
@@ -1923,7 +2068,6 @@ int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
return 0;
}
}
-
void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
{
Object *ob;
@@ -2030,7 +2174,6 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
}
}
}
-
int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
{
PointCache *cache;
@@ -2093,7 +2236,6 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
return (reset || clear || after);
}
-
int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
{
PTCacheID pid;
@@ -2235,8 +2377,10 @@ void BKE_ptcache_free_mem(ListBase *mem_cache)
PTCacheMem *pm = mem_cache->first;
if(pm) {
- for(; pm; pm=pm->next)
+ for(; pm; pm=pm->next) {
ptcache_data_free(pm);
+ ptcache_extra_free(pm);
+ }
BLI_freelistN(mem_cache);
}
@@ -2549,120 +2693,51 @@ void BKE_ptcache_bake(PTCacheBaker* baker)
void BKE_ptcache_disk_to_mem(PTCacheID *pid)
{
PointCache *cache = pid->cache;
- PTCacheFile *pf;
- PTCacheMem *pm;
-
+ PTCacheMem *pm = NULL;
+ int baked = cache->flag & PTCACHE_BAKED;
int cfra, sfra = cache->startframe, efra = cache->endframe;
- int i;
-
- BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
-
- for(cfra=sfra; cfra <= efra; cfra++) {
- pf = ptcache_file_open(pid, PTCACHE_FILE_READ, cfra);
-
- if(pf) {
- if(!ptcache_file_header_begin_read(pf)) {
- printf("Can't yet convert old cache format\n");
- cache->flag |= PTCACHE_DISK_CACHE;
- ptcache_file_close(pf);
- return;
- }
-
- if(pf->type != pid->type || !pid->read_header(pf)) {
- cache->flag |= PTCACHE_DISK_CACHE;
- ptcache_file_close(pf);
- return;
- }
-
- pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
-
- pm->totpoint = pf->totpoint;
- pm->data_types = pf->data_types;
- pm->frame = cfra;
- ptcache_data_alloc(pm);
- BKE_ptcache_mem_pointers_init(pm);
- ptcache_file_pointers_init(pf);
+ /* Remove possible bake flag to allow clear */
+ cache->flag &= ~PTCACHE_BAKED;
- for(i=0; i<pm->totpoint; i++) {
- if(!ptcache_file_data_read(pf)) {
- printf("Error reading from disk cache\n");
-
- cache->flag |= PTCACHE_DISK_CACHE;
-
- ptcache_data_free(pm);
- MEM_freeN(pm);
- ptcache_file_close(pf);
+ /* PTCACHE_DISK_CACHE flag was cleared already */
+ BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
- return;
- }
- ptcache_data_copy(pf->cur, pm->cur);
- BKE_ptcache_mem_pointers_incr(pm);
- }
+ /* restore possible bake flag */
+ cache->flag |= baked;
- ptcache_make_index_array(pm, pid->totpoint(pid->calldata, cfra));
+ for(cfra=sfra; cfra <= efra; cfra++) {
+ pm = ptcache_disk_frame_to_mem(pid, cfra);
+ if(pm)
BLI_addtail(&pid->cache->mem_cache, pm);
-
- ptcache_file_close(pf);
- }
}
-
}
void BKE_ptcache_mem_to_disk(PTCacheID *pid)
{
PointCache *cache = pid->cache;
- PTCacheFile *pf;
- PTCacheMem *pm;
- int i;
+ PTCacheMem *pm = cache->mem_cache.first;
+ int baked = cache->flag & PTCACHE_BAKED;
- pm = cache->mem_cache.first;
+ /* Remove possible bake flag to allow clear */
+ cache->flag &= ~PTCACHE_BAKED;
+ /* PTCACHE_DISK_CACHE flag was set already */
BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
- for(; pm; pm=pm->next) {
- pf = ptcache_file_open(pid, PTCACHE_FILE_WRITE, pm->frame);
-
- if(pf) {
- pf->data_types = pm->data_types;
- pf->totpoint = pm->totpoint;
- pf->type = pid->type;
+ /* restore possible bake flag */
+ cache->flag |= baked;
- BKE_ptcache_mem_pointers_init(pm);
- ptcache_file_pointers_init(pf);
-
- if(!ptcache_file_header_begin_write(pf) || !pid->write_header(pf)) {
- if (G.f & G_DEBUG)
- printf("Error writing to disk cache\n");
- cache->flag &= ~PTCACHE_DISK_CACHE;
-
- ptcache_file_close(pf);
- return;
- }
-
- for(i=0; i<pm->totpoint; i++) {
- ptcache_data_copy(pm->cur, pf->cur);
- if(!ptcache_file_data_write(pf)) {
- if (G.f & G_DEBUG)
- printf("Error writing to disk cache\n");
- cache->flag &= ~PTCACHE_DISK_CACHE;
-
- ptcache_file_close(pf);
- return;
- }
- BKE_ptcache_mem_pointers_incr(pm);
- }
-
- ptcache_file_close(pf);
-
- /* write info file */
- if(cache->flag & PTCACHE_BAKED)
- BKE_ptcache_write(pid, 0);
+ for(; pm; pm=pm->next) {
+ if(ptcache_mem_frame_to_disk(pid, pm)==0) {
+ cache->flag &= ~PTCACHE_DISK_CACHE;
+ break;
}
- else
- if (G.f & G_DEBUG)
- printf("Error creating disk cache file\n");
}
+
+ /* write info file */
+ if(cache->flag & PTCACHE_BAKED)
+ BKE_ptcache_write(pid, 0);
}
void BKE_ptcache_toggle_disk_cache(PTCacheID *pid)
{
@@ -2676,6 +2751,11 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid)
return;
}
+ if(cache->cached_frames) {
+ MEM_freeN(cache->cached_frames);
+ cache->cached_frames=NULL;
+ }
+
if(cache->flag & PTCACHE_DISK_CACHE)
BKE_ptcache_mem_to_disk(pid);
else
@@ -2687,11 +2767,6 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid)
cache->last_exact = last_exact;
- if(cache->cached_frames) {
- MEM_freeN(cache->cached_frames);
- cache->cached_frames=NULL;
- }
-
BKE_ptcache_id_time(pid, NULL, 0.0f, NULL, NULL, NULL);
BKE_ptcache_update_info(pid);
@@ -2854,6 +2929,7 @@ void BKE_ptcache_load_external(PTCacheID *pid)
void BKE_ptcache_update_info(PTCacheID *pid)
{
PointCache *cache = pid->cache;
+ PTCacheExtra *extra = NULL;
int totframes = 0;
char mem_info[64];
@@ -2903,7 +2979,16 @@ void BKE_ptcache_update_info(PTCacheID *pid)
for(; pm; pm=pm->next) {
for(i=0; i<BPHYS_TOT_DATA; i++)
- bytes += pm->data[i] ? MEM_allocN_len(pm->data[i]) : 0.0f;
+ bytes += MEM_allocN_len(pm->data[i]);
+
+ for(extra=pm->extradata.first; extra; extra=extra->next) {
+ bytes += MEM_allocN_len(extra->data);
+ bytes += sizeof(PTCacheExtra);
+ }
+
+ bytes += MEM_allocN_len(pm->index_array);
+ bytes += sizeof(PTCacheMem);
+
totframes++;
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 19f872fbd40..1b5d1093373 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -642,7 +642,7 @@ void calc_sequence(Scene *scene, Sequence *seq)
void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range)
{
char str[FILE_MAXDIR+FILE_MAXFILE];
- int prev_startdisp, prev_enddisp;
+ int prev_startdisp=0, prev_enddisp=0;
/* note: dont rename the strip, will break animation curves */
if (ELEM5(seq->type, SEQ_MOVIE, SEQ_IMAGE, SEQ_SOUND, SEQ_SCENE, SEQ_META)==0) {
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index babe4209a31..9a0f278bcd0 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -1376,7 +1376,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
}
/* try to read from cache */
- if(BKE_ptcache_read(&pid, (float)framenr, scene->r.frs_sec) == PTCACHE_READ_EXACT) {
+ if(BKE_ptcache_read(&pid, (float)framenr) == PTCACHE_READ_EXACT) {
BKE_ptcache_validate(cache, framenr);
smd->time = framenr;
return;
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 4653562e5f4..eb56331acfb 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -4134,7 +4134,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
}
/* try to read from cache */
- cache_result = BKE_ptcache_read(&pid, framenr, scene->r.frs_sec);
+ cache_result = BKE_ptcache_read(&pid, framenr);
if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
softbody_to_object(ob, vertexCos, numVerts, sb->local);
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index bbdc188d580..bb3a31a0977 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -2710,9 +2710,13 @@ int setcurr_tab_spaces (Text *text, int space)
}
if(strstr(text->curl->line, word))
{
- //if we find a : then add a tab but not if it is in a comment
+ /* if we find a ':' on this line, then add a tab but not if it is:
+ * 1) in a comment
+ * 2) within an identifier
+ * 3) after the cursor (text->curc), i.e. when creating space before a function def [#25414]
+ */
int a, indent = 0;
- for(a=0; text->curl->line[a] != '\0'; a++)
+ for(a=0; (a < text->curc) && (text->curl->line[a] != '\0'); a++)
{
if (text->curl->line[a]=='#') {
break;