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
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-04-10 15:39:20 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-04-10 15:39:20 +0400
commit1fe5302cce8de1bad875ad29a3fcff06d0c59654 (patch)
tree7ad40e8f9ee90d0c16185cf4dcb06ee025765b58 /source
parent36288dabb8e39910b81dc09067db9065cc3004b9 (diff)
Point Cache Refactoring
======================= Caching and Baking: - The point cache is now cleared on DAG_object_flush_update(), and not cleared for time dependency graph updates. - There is now a Bake button instead of Protect. Also cache start and end frames were added to softbody and particles. - The cloth autoprotect feature was removed. - The Ctrl+B menu now also bakes cloth and particles next to softbody and fluids. Additionally there are now frree bake and free cache menu entries. - The point cache api has been changed. There is now a PTCacheID struct for each point cache type that can be filled and then used to call the point cache functions. - PointCache struct was added to DNA and is automatically allocated for each physics type. - Soft body now supports Bake Editing just like cloth. - Tried to make the systems deal consistently with time ipo's and offsets. Still not sure it all works correct, but too complicated to solve completely now. Library Linking: - Added some more warnings to prevent editing settings on library linked objects. - Linked objects now read from the cache located next to the original library file, and never write to it. This restores old behavior for softbodies. For local simulation the mesh and not the object should be linked. - Dupligroups and proxies can't create local point caches at the moment, how to implement that I'm not sure. We probably need a proxy point cache for that to work (ugh). Physics UI: - Renamed deflection panel to collision for consistency and reorganized the buttons. Also removed some softbody collision buttons from the softbody panel that were duplicated in this panel for cloth. - Tweaked field panel buttons to not jump around when changing options. - Tabbing e.g. Soft Body Collision into the Soft Body panel, it now only shows Collision to make the panel names readable. - I tried to make enabled/disabling physics more consistent, since all three system did things different. Now the two modifier buttons to enable the modifier for the viewport and rendering are also duplicated in the physics panels. Toggling the Soft Body and Cloth buttons now both remove their modifiers. - Fixed modifier error drawing glitch. Particles: - Particles are now recalculated more often than before. Previously it did partial updates based on the changes, but that doesn't work well with DAG_object_flush_update() .. - Fixed memory leak loading keyed particle system. Now keys are not written to file anymore but always created after loading. - Make particle threads work with autothreads. Continue Physics: - The timeline play now has a Continue Physics option in the playback menu, which keeps the simulations going without writing them to the cache. - This doesn't always work that well, some changes are not immediately updated, but this can be improved later. Still it's fun to get a feel for the physics. Todo: - Point cache can get out of sync with and undo and changing a file without saving it. - Change the point cache file format to store a version (so old point cache files can be either converted or at least ignored), and to do correct endian conversion. - Menu item and/or buttons for Ctrl+B. - A system("rm ..") was changed to remove() since the former is very slow for clearing point caches. These system() calls were already giving trouble in a bug in the tracker, but really most use of this system("") should be changed and tested. - The Soft Body Collision and Clot Collision panel titles don't mention there's point cache settings there too, doing that makes them unreadable with the default panel setup.. but may need to make the names longer anyway.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_cloth.h14
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h2
-rw-r--r--source/blender/blenkernel/BKE_particle.h15
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h74
-rw-r--r--source/blender/blenkernel/BKE_softbody.h5
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c6
-rw-r--r--source/blender/blenkernel/intern/cloth.c539
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c76
-rw-r--r--source/blender/blenkernel/intern/modifier.c12
-rw-r--r--source/blender/blenkernel/intern/object.c15
-rw-r--r--source/blender/blenkernel/intern/particle.c48
-rw-r--r--source/blender/blenkernel/intern/particle_system.c475
-rw-r--r--source/blender/blenkernel/intern/pointcache.c383
-rw-r--r--source/blender/blenkernel/intern/softbody.c732
-rw-r--r--source/blender/blenlib/intern/fileops.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c68
-rw-r--r--source/blender/blenloader/intern/writefile.c12
-rw-r--r--source/blender/include/butspace.h7
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h21
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h1
-rw-r--r--source/blender/makesdna/DNA_object_force.h29
-rw-r--r--source/blender/makesdna/DNA_particle_types.h8
-rw-r--r--source/blender/makesdna/DNA_space_types.h1
-rw-r--r--source/blender/src/buttons_editing.c29
-rw-r--r--source/blender/src/buttons_object.c1055
-rw-r--r--source/blender/src/drawview.c28
-rw-r--r--source/blender/src/edit.c11
-rw-r--r--source/blender/src/editipo.c14
-rw-r--r--source/blender/src/editmesh.c285
-rw-r--r--source/blender/src/editnla.c2
-rw-r--r--source/blender/src/editobject.c31
-rw-r--r--source/blender/src/editparticle.c3
-rw-r--r--source/blender/src/fluidsim.c8
-rw-r--r--source/blender/src/header_time.c40
-rw-r--r--source/blender/src/interface_panel.c18
-rw-r--r--source/blender/src/poselib.c24
-rw-r--r--source/blender/src/space.c27
-rw-r--r--source/blender/src/toets.c4
-rw-r--r--source/blender/src/transform.c12
-rw-r--r--source/blender/src/transform_conversions.c23
-rw-r--r--source/blender/src/transform_generics.c36
-rw-r--r--source/blender/src/vpaint.c17
42 files changed, 2462 insertions, 1750 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 418102aa973..f1a439e2e04 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -147,16 +147,18 @@ ClothSpring;
/* These are the bits used in SimSettings.flags. */
typedef enum
{
- CLOTH_SIMSETTINGS_FLAG_RESET = ( 1 << 1 ), // The CM object requires a reinitializaiton.
+ //CLOTH_SIMSETTINGS_FLAG_RESET = ( 1 << 1 ), // The CM object requires a reinitializaiton.
CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ),// object is only collision object, no cloth simulation is done
CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled
CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled
- CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled
- CLOTH_SIMSETTINGS_FLAG_EDITMODE = ( 1 << 6 ), // are we in editmode? -several things disabled
- CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = ( 1 << 7 ), /* force cache freeing */
+ //CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled
+ //CLOTH_SIMSETTINGS_FLAG_EDITMODE = ( 1 << 6 ), // are we in editmode? -several things disabled
+ //CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = ( 1 << 7 ), /* force cache freeing */
CLOTH_SIMSETTINGS_FLAG_SCALING = ( 1 << 8 ), /* is advanced scaling active? */
- CLOTH_SIMSETTINGS_FLAG_LOADED = ( 1 << 9 ), /* did we just got load? */
- CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT = ( 1 << 10 ), /* is autoprotect enabled? */
+ //CLOTH_SIMSETTINGS_FLAG_LOADED = ( 1 << 9 ), /* did we just got load? */
+ //CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT = ( 1 << 10 ), /* is autoprotect enabled? */
+ //CLOTH_SIMSETTINGS_FLAG_CCACHE_OUTDATED = (1 << 11), /* while protected, did cache get outdated? */
+ CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12) /* edit cache in editmode */
} CLOTH_SIMSETTINGS_FLAGS;
/* COLLISION FLAGS */
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 294f61e54bd..36f26d42cee 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -104,7 +104,7 @@ void DAG_scene_update_flags(struct Scene *sce, unsigned int lay);
void DAG_object_update_flags(struct Scene *sce, struct Object *ob, unsigned int lay);
/* flushes all recalc flags in objects down the dependency tree */
-void DAG_scene_flush_update(struct Scene *sce, unsigned int lay);
+void DAG_scene_flush_update(struct Scene *sce, unsigned int lay, int time);
/* flushes all recalc flags for this object down the dependency tree */
void DAG_object_flush_update(struct Scene *sce, struct Object *ob, short flag);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index f134c4597c1..45be121661b 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -41,6 +41,7 @@
struct ParticleSystemModifierData;
struct ParticleSystem;
struct ParticleKey;
+struct ParticleSettings;
struct HairKey;
struct Main;
@@ -222,9 +223,6 @@ void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot);
int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
-void clear_particles_from_cache(struct Object *ob, struct ParticleSystem *psys, int cfra);
-//void psys_remove_from_particle_list(struct Object *ob, short nbr, struct ParticleSystem *psys);
-
void psys_interpolate_uvs(struct MTFace *tface, int quad, float *uv, float *uvco);
void psys_interpolate_mcol(struct MCol *mcol, int quad, float *uv, struct MCol *mc);
@@ -237,6 +235,10 @@ struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
void psys_flush_settings(struct ParticleSettings *part, int event, int hair_recalc);
+struct LinkNode *psys_using_settings(struct ParticleSettings *part, int flush_update);
+void psys_changed_type(struct ParticleSystem *psys);
+void psys_reset(struct ParticleSystem *psys, int mode);
+
void psys_find_parents(struct Object *ob, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys);
void psys_cache_paths(struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate);
@@ -251,7 +253,7 @@ int psys_get_particle_state(struct Object *ob, struct ParticleSystem *psys, int
void psys_get_dupli_texture(struct Object *ob, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco);
void psys_get_dupli_path_transform(struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale);
-ParticleThread *psys_threads_create(struct Object *ob, struct ParticleSystem *psys, int totthread);
+ParticleThread *psys_threads_create(struct Object *ob, struct ParticleSystem *psys);
int psys_threads_init_distribution(ParticleThread *threads, struct DerivedMesh *dm, int from);
int psys_threads_init_path(ParticleThread *threads, float cfra, int editupdate);
void psys_threads_free(ParticleThread *threads);
@@ -298,6 +300,11 @@ void do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state,
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node);
+/* psys_reset */
+#define PSYS_RESET_ALL 1
+#define PSYS_RESET_DEPSGRAPH 2
+#define PSYS_RESET_CHILDREN 3
+
/* ParticleEffectorCache->type */
#define PSYS_EC_EFFECTOR 1
#define PSYS_EC_DEFLECT 2
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 12068f7dedf..5bc467465a8 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -31,24 +31,84 @@
#include "DNA_ID.h"
-/* options for clearing pointcache - used for BKE_ptcache_id_clear
- Before and after are non inclusive (they wont remove the cfra) */
+/* Point cache clearing option, for BKE_ptcache_id_clear, before
+ * and after are non inclusive (they wont remove the cfra) */
#define PTCACHE_CLEAR_ALL 0
#define PTCACHE_CLEAR_FRAME 1
#define PTCACHE_CLEAR_BEFORE 2
#define PTCACHE_CLEAR_AFTER 3
+/* Point cache reset options */
+#define PTCACHE_RESET_DEPSGRAPH 0
+#define PTCACHE_RESET_BAKED 1
+#define PTCACHE_RESET_OUTDATED 2
+
/* Add the blendfile name after blendcache_ */
#define PTCACHE_EXT ".bphys"
#define PTCACHE_PATH "blendcache_"
+/* File open options, for BKE_ptcache_file_open */
+#define PTCACHE_FILE_READ 0
+#define PTCACHE_FILE_WRITE 1
+
+/* PTCacheID types */
+#define PTCACHE_TYPE_SOFTBODY 0
+#define PTCACHE_TYPE_PARTICLES 1
+#define PTCACHE_TYPE_CLOTH 2
+
+/* Structs */
+struct Object;
+struct SoftBody;
+struct ParticleSystem;
+struct ClothModifierData;
+struct PointCache;
+struct ListBase;
+
+typedef struct PTCacheFile {
+ FILE *fp;
+} PTCacheFile;
+
+typedef struct PTCacheID {
+ struct PTCacheID *next, *prev;
+
+ struct Object *ob;
+ void *data;
+ int type;
+ int stack_index;
+
+ struct PointCache *cache;
+} PTCacheID;
+
+/* Creating ID's */
+void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct SoftBody *sb);
+void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys);
+void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd);
+
+void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob);
+
/* Global funcs */
void BKE_ptcache_remove(void);
-/* Object spesific funcs */
-int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext);
-FILE * BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index);
-void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index);
-int BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index);
+/* ID specific functions */
+void BKE_ptcache_id_clear(PTCacheID *id, int mode, int cfra);
+int BKE_ptcache_id_exist(PTCacheID *id, int cfra);
+int BKE_ptcache_id_reset(PTCacheID *id, int mode);
+void BKE_ptcache_id_time(PTCacheID *pid, float cfra, int *startframe, int *endframe, float *timescale);
+int BKE_ptcache_object_reset(struct Object *ob, int mode);
+
+/* File reading/writing */
+PTCacheFile *BKE_ptcache_file_open(PTCacheID *id, int mode, int cfra);
+void BKE_ptcache_file_close(PTCacheFile *pf);
+int BKE_ptcache_file_read_floats(PTCacheFile *pf, float *f, int tot);
+int BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot);
+
+/* Continue physics */
+void BKE_ptcache_set_continue_physics(int enable);
+int BKE_ptcache_get_continue_physics(void);
+
+/* Point Cache */
+struct PointCache *BKE_ptcache_add(void);
+void BKE_ptcache_free(struct PointCache *cache);
+struct PointCache *BKE_ptcache_copy(struct PointCache *cache);
#endif
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index 91bc4cc070d..8a3688fbe09 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -55,7 +55,8 @@ extern struct SoftBody *sbNew(void);
/* frees internal data and softbody itself */
extern void sbFree(struct SoftBody *sb);
-extern void softbody_clear_cache(struct Object *ob, float framenr);
+/* frees simulation data to reset simulation */
+extern void sbFreeSimulation(struct SoftBody *sb);
/* do one simul step, reading and writing vertex locs from given array */
extern void sbObjectStep(struct Object *ob, float framnr, float (*vertexCos)[3], int numVerts);
@@ -67,6 +68,8 @@ extern void sbObjectToSoftbody(struct Object *ob);
/* pass NULL to unlink again */
extern void sbSetInterruptCallBack(int (*f)(void));
+/* writing to cache for bake editing */
+extern void sbWriteCache(struct Object *ob, int framenr);
#endif
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index b0103fa812b..7624ca04984 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2012,8 +2012,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
if((md->mode & required_mode) != required_mode) continue;
if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue;
if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
- modifier_setError(md, "Internal error, modifier requires "
- "original data (bad stack position).");
+ modifier_setError(md, "Modifier requires original data, bad stack position.");
continue;
}
if(mti->isDisabled && mti->isDisabled(md)) continue;
@@ -2194,8 +2193,7 @@ static int editmesh_modifier_is_enabled(ModifierData *md, DerivedMesh *dm)
if((md->mode & required_mode) != required_mode) return 0;
if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
- modifier_setError(md, "Internal error, modifier requires"
- "original data (bad stack position).");
+ modifier_setError(md, "Modifier requires original data, bad stack position.");
return 0;
}
if(mti->isDisabled && mti->isDisabled(md)) return 0;
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 6123b1b5e35..15f4051c109 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -34,6 +34,7 @@
#include "DNA_cloth_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_object_force.h"
#include "DNA_scene_types.h"
#include "BKE_deform.h"
@@ -92,7 +93,7 @@ static CM_SOLVER_DEF solvers [] =
*/
static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm);
static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
-static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr);
+static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first);
int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
@@ -121,18 +122,11 @@ void cloth_init ( ClothModifierData *clmd )
clmd->sim_parms->Cvi = 1.0;
clmd->sim_parms->mass = 0.3f;
clmd->sim_parms->stepsPerFrame = 5;
- clmd->sim_parms->sim_time = 1.0;
- clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT;
+ clmd->sim_parms->flags = 0;
clmd->sim_parms->solver_type = 0;
clmd->sim_parms->preroll = 0;
clmd->sim_parms->maxspringlen = 10;
- clmd->sim_parms->firstframe = 1;
- clmd->sim_parms->lastframe = 250;
clmd->sim_parms->vgroup_mass = 0;
- clmd->sim_parms->lastcachedframe = 0;
- clmd->sim_parms->editedframe = 0;
- clmd->sim_parms->autoprotect = 25;
- clmd->sim_parms->firstcachedframe = -1.0;
clmd->sim_parms->avg_spring_len = 0.0;
clmd->sim_parms->presets = 2; /* cotton as start setting */
clmd->sim_parms->timescale = 1.0f; /* speed factor, describes how fast cloth moves */
@@ -246,395 +240,266 @@ int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
{
- FILE *fp = NULL;
- int stack_index = -1;
- unsigned int a, ret = 1;
+ PTCacheID pid;
+ PTCacheFile *pf;
Cloth *cloth = clmd->clothObject;
+ unsigned int a, ret = 1;
if(!cloth)
return 0;
- stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
-
- fp = BKE_ptcache_id_fopen((ID *)ob, 'r', framenr, stack_index);
- if(!fp)
- ret = 0;
- else {
- for(a = 0; a < cloth->numverts; a++)
- {
- if(fread(&cloth->verts[a].x, sizeof(float), 3, fp) != 3)
- {
+ BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+ pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, framenr);
+ if(pf) {
+ for(a = 0; a < cloth->numverts; a++) {
+ if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].x, 3)) {
ret = 0;
break;
}
- if(fread(&cloth->verts[a].xconst, sizeof(float), 3, fp) != 3)
- {
+ if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].xconst, 3)) {
ret = 0;
break;
}
- if(fread(&cloth->verts[a].v, sizeof(float), 3, fp) != 3)
- {
+ if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].v, 3)) {
ret = 0;
break;
}
}
- fclose(fp);
-
- if(clmd->sim_parms->lastcachedframe < framenr)
- {
- if(G.rt > 0)
- printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe);
- }
-
- if(G.rt > 0)
- printf("cloth_read_cache: %f successfully \n", framenr);
+ BKE_ptcache_file_close(pf);
}
-
- if(G.rt > 0)
- printf("cloth_read_cache: %f\n", framenr);
+ else
+ ret = 0;
return ret;
}
void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
{
- int stack_index = -1;
+ PTCacheID pid;
+ BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
// don't do anything as long as we're in editmode!
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
- {
- /* delete cache free request */
- clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
-
+ if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
return;
- }
-
- /* clear cache if specific frame cleaning requested or cache is not protected */
- if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE))
- {
- stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
-
- BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index);
-
- /* update last cached frame # */
- clmd->sim_parms->lastcachedframe = framenr;
-
- /* update first cached frame # */
- if((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe >=0.0))
- clmd->sim_parms->firstcachedframe = -1.0;
-
- if(G.rt > 0)
- printf("cloth_clear_cache: %f\n", framenr);
- }
-
- /* delete cache free request */
- clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
-
+ BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
}
+
void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
{
- FILE *fp = NULL;
- int stack_index = -1;
- unsigned int a;
Cloth *cloth = clmd->clothObject;
-
- if(G.rt > 0)
- printf("cloth_write_cache: %f\n", framenr);
+ PTCacheID pid;
+ PTCacheFile *pf;
+ unsigned int a;
if(!cloth)
- {
- if(G.rt > 0)
- printf("cloth_write_cache: no cloth\n");
return;
- }
-
- stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
- fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index);
- if(!fp)
- {
- if(G.rt > 0)
- printf("cloth_write_cache: no fp\n");
+ BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+ pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, framenr);
+ if(!pf)
return;
- }
- for(a = 0; a < cloth->numverts; a++)
- {
- fwrite(&cloth->verts[a].x, sizeof(float),3,fp);
- fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp);
- fwrite(&cloth->verts[a].v, sizeof(float),3,fp);
+ for(a = 0; a < cloth->numverts; a++) {
+ BKE_ptcache_file_write_floats(pf, cloth->verts[a].x, 3);
+ BKE_ptcache_file_write_floats(pf, cloth->verts[a].xconst, 3);
+ BKE_ptcache_file_write_floats(pf, cloth->verts[a].v, 3);
}
- /* update last cached frame # */
- clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr);
+ BKE_ptcache_file_close(pf);
+}
+
+static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
+{
+ PointCache *cache;
+
+ cache= clmd->point_cache;
+
+ /* initialize simulation data if it didn't exist already */
+ if(clmd->clothObject == NULL) {
+ if(!cloth_from_object(ob, clmd, result, framenr, 1)) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ return 0;
+ }
+
+ if(clmd->clothObject == NULL) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ return 0;
+ }
- /* update first cached frame # */
- if((clmd->sim_parms->firstcachedframe < 0.0) || ((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe > 0.0)))
- clmd->sim_parms->firstcachedframe = framenr;
+ implicit_set_positions(clmd);
+ }
+
+ return 1;
+}
+
+static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
+{
+ ClothVertex *verts = NULL;
+ Cloth *cloth;
+ ListBase *effectors = NULL;
+ MVert *mvert;
+ int i, ret = 0;
+
+ /* simulate 1 frame forward */
+ cloth = clmd->clothObject;
+ verts = cloth->verts;
+ mvert = result->getVertArray(result);
+
+ /* force any pinned verts to their constrained location. */
+ for(i = 0; i < clmd->clothObject->numverts; i++, verts++) {
+ /* save the previous position. */
+ VECCOPY(verts->xold, verts->xconst);
+ VECCOPY(verts->txold, verts->x);
+
+ /* Get the current position. */
+ VECCOPY(verts->xconst, mvert[i].co);
+ Mat4MulVecfl(ob->obmat, verts->xconst);
+ }
- if(G.rt > 0)
- printf("lcf: %d, framenr: %f\n", clmd->sim_parms->lastcachedframe, framenr);
+ tstart();
+
+ /* call the solver. */
+ if(solvers [clmd->sim_parms->solver_type].solver)
+ ret = solvers[clmd->sim_parms->solver_type].solver(ob, framenr, clmd, effectors);
+
+ tend();
- fclose(fp);
+ /* printf ( "Cloth simulation time: %f\n", ( float ) tval() ); */
+
+ return ret;
}
/************************************************
* clothModifier_do - main simulation function
************************************************/
-DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
-
+DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
{
- unsigned int i;
- Cloth *cloth = clmd->clothObject;
- float framenr = G.scene->r.cfra;
- float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
- ListBase *effectors = NULL;
- ClothVertex *verts = NULL;
- float deltaTime = current_time - clmd->sim_parms->sim_time;
- unsigned int numverts = -1;
- unsigned int numedges = -1;
- unsigned int numfaces = -1;
- MVert *mvert = NULL;
- MEdge *medge = NULL;
- MFace *mface = NULL;
- DerivedMesh *result = NULL;
- int ret = 0;
-
- if(G.rt > 0)
- printf("clothModifier_do start\n");
-
- /* we're getting called two times during file load,
- resulting in a not valid G.relbase on the first time (cache makes problems)
- --> just return back */
- if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED) && (!G.relbase_valid))
- {
- clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_LOADED;
- return dm;
- }
-
+ DerivedMesh *result;
+ PointCache *cache;
+ PTCacheID pid;
+ float timescale;
+ int framedelta, framenr, startframe, endframe;
+
+ framenr= (int)G.scene->r.cfra;
+ cache= clmd->point_cache;
result = CDDM_copy(dm);
-
- if(!result)
- {
+
+ BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+ BKE_ptcache_id_time(&pid, framenr, &startframe, &endframe, &timescale);
+ clmd->sim_parms->timescale= timescale;
+
+ /* TODO: use timescale somewhere! */
+
+ if(!result) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
return dm;
}
- numverts = result->getNumVerts(result);
- numedges = result->getNumEdges(result);
- numfaces = result->getNumFaces(result);
- mvert = result->getVertArray(result);
- medge = result->getEdgeArray(result);
- mface = result->getFaceArray(result);
-
- /* check if cache is active / if file is already saved */
- /*
- if ((!G.relbase_valid) && ( deltaTime != 1.0f ))
- {
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
-}
- */
-
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET)
- {
- cloth_free_modifier (ob, clmd);
- if(G.rt > 0)
- printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n");
-
- // prevent rebuilding of cloth each time you move backward
- if(deltaTime < 0.0)
+ /* verify we still have the same number of vertices, if not do nothing.
+ * note that this should only happen if the number of vertices changes
+ * during an animation due to a preceding modifier, this should not
+ * happen because of object changes! */
+ if(clmd->clothObject) {
+ if(result->getNumVerts(result) != clmd->clothObject->numverts) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
return result;
+ }
}
// unused in the moment, calculated seperately in implicit.c
clmd->sim_parms->dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
-
- if ( ( clmd->clothObject == NULL ) || (clmd->clothObject && (numverts != clmd->clothObject->numverts )) )
- {
- /* only force free the cache if we have a different number of verts */
- if(clmd->clothObject && (numverts != clmd->clothObject->numverts ))
- {
- if(G.rt > 0)
- printf("Force Freeing: numverts != clmd->clothObject->numverts\n");
-
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
- cloth_free_modifier ( ob, clmd );
- }
-
- cloth_clear_cache(ob, clmd, 0);
-
- if ( !cloth_from_object ( ob, clmd, result, framenr ) )
- return result;
-
- if ( clmd->clothObject == NULL )
+
+ /* handle continuous simulation with the play button */
+ if(BKE_ptcache_get_continue_physics()) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+
+ /* do simulation */
+ if(!do_init_cloth(ob, clmd, result, framenr))
return result;
-
- cloth = clmd->clothObject;
-
- if(!cloth_read_cache(ob, clmd, framenr))
- {
- /* save first frame in case we have a reseted object
- and we move one frame forward.
- In that case we would only start with the SECOND frame
- if we don't save the current state before
- TODO PROBLEM: IMHO we can't track external movement from the
- first frame in this case! */
- /*
- if ( deltaTime == 1.0f )
- cloth_write_cache(ob, clmd, framenr-1.0);
- */
- if(G.rt > 0)
- printf("cloth_from_object NO cloth_read_cache cloth_write_cache\n");
- }
- else
- {
- if(G.rt > 0)
- printf("cloth_from_object cloth_read_cache\n");
-
- implicit_set_positions(clmd);
- }
-
- clmd->sim_parms->sim_time = current_time;
- }
-
- // only be active during a specific period:
- // that's "first frame" and "last frame" on GUI
- if ( current_time < clmd->sim_parms->firstframe )
- {
- if(G.rt > 0)
- printf("current_time < clmd->sim_parms->firstframe\n");
+
+ do_step_cloth(ob, clmd, result, framenr);
+ cloth_to_object(ob, clmd, result);
+
return result;
}
- else if ( current_time > clmd->sim_parms->lastframe )
- {
- int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
-
- if(G.rt > 0)
- printf("current_time > clmd->sim_parms->lastframe\n");
-
- if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index))
- {
- if(cloth_read_cache(ob, clmd, clmd->sim_parms->lastcachedframe))
- {
- implicit_set_positions(clmd);
-
- // Copy the result back to the object.
- cloth_to_object (ob, clmd, result);
- }
- }
+
+ /* simulation is only active during a specific period */
+ if(framenr < startframe) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
return result;
}
-
- // check for autoprotection, but only if cache active
- if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT)
- {
- if((framenr >= clmd->sim_parms->autoprotect) && (G.relbase_valid))
- {
- if(G.rt > 0)
- printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect);
-
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
- }
+ else if(framenr > endframe) {
+ framenr= endframe;
}
- /* nice moving one frame forward */
- if ( deltaTime == 1.0f )
- {
- clmd->sim_parms->sim_time = current_time;
-
- if(G.rt > 0)
- printf("clothModifier_do deltaTime=1\n");
-
- if(!cloth_read_cache(ob, clmd, framenr))
- {
- verts = cloth->verts;
+ /* dt is unused at the moment, calculated seperately in implicit.c */
+ clmd->sim_parms->dt= 1.0f/clmd->sim_parms->stepsPerFrame;
- // Force any pinned verts to their constrained location.
- for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
- {
- // Save the previous position.
- VECCOPY ( verts->xold, verts->xconst );
- VECCOPY ( verts->txold, verts->x );
+ if(cache->flag & PTCACHE_SIMULATION_VALID)
+ framedelta= framenr - cache->simframe;
+ else
+ framedelta= -1;
- // Get the current position.
- VECCOPY ( verts->xconst, mvert[i].co );
- Mat4MulVecfl ( ob->obmat, verts->xconst );
- }
-
- tstart();
+ /* initialize simulation data if it didn't exist already */
+ if(!do_init_cloth(ob, clmd, result, framenr))
+ return result;
- // Call the solver.
- if ( solvers [clmd->sim_parms->solver_type].solver )
- {
- ret = solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors );
- }
+ /* try to read from cache */
+ if(cloth_read_cache(ob, clmd, framenr)) {
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
- tend();
- // printf ( "Cloth simulation time: %f\n", ( float ) tval() );
-
- if(ret)
- cloth_write_cache(ob, clmd, framenr);
- else
- clmd->sim_parms->sim_time--;
- }
- else
- {
- if(G.rt > 0)
- printf("clothModifier_do deltaTime=1 cacheread\n");
- implicit_set_positions(clmd);
- }
-
- // Copy the result back to the object.
+ implicit_set_positions(clmd);
cloth_to_object (ob, clmd, result);
+
+ return result;
}
- else if(deltaTime == 0.0f)
- {
- if(G.rt > 0)
- printf("dt = 0, %f\n", framenr);
- if(cloth_read_cache(ob, clmd, framenr))
- {
- cloth_to_object (ob, clmd, result);
- implicit_set_positions(clmd);
- }
- else /* same cache parts are missing */
- {
- /* jump to a non-existing frame makes sim reset if cache is not protected */
- if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
- {
- /* prevent freeing when used with vectorblur */
- if(!useRenderParams)
- {
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
- cloth_clear_cache(ob, clmd, 0);
-
- cloth_write_cache(ob, clmd, framenr);
- }
- }
- }
+ else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
+ /* if baked and nothing in cache, do nothing */
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ return result;
}
- else
- {
- if(G.rt > 0)
- printf("dt > 1.0 || dt < 0.0, %f, st: %f, ct: %f\n", framenr, clmd->sim_parms->sim_time, current_time);
- if(cloth_read_cache(ob, clmd, framenr))
- {
- cloth_to_object (ob, clmd, result);
- implicit_set_positions(clmd);
+
+ if(framenr == startframe) {
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
+
+ /* don't write cache on first frame, but on second frame write
+ * cache for frame 1 and 2 */
+ }
+ else if(framedelta == 1) {
+ /* if on second frame, write cache for first frame */
+ if(framenr == startframe+1)
+ cloth_write_cache(ob, clmd, startframe);
+
+ /* do simulation */
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
+
+ if(!do_step_cloth(ob, clmd, result, framenr)) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
}
else
- {
- /* jump to a non-existing frame makes sim reset if cache is not protected */
- if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
- {
- /* prevent freeing when used with vectorblur */
- if(!useRenderParams)
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- }
- }
- clmd->sim_parms->sim_time = current_time;
+ cloth_write_cache(ob, clmd, framenr);
+
+ cloth_to_object (ob, clmd, result);
}
-
+ else {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ }
+
return result;
}
@@ -702,7 +567,6 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd )
MEM_freeN ( cloth );
clmd->clothObject = NULL;
}
- clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_RESET;
}
/* frees all */
@@ -888,13 +752,12 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
}
}
-static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr)
+static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first)
{
unsigned int i = 0;
MVert *mvert = NULL;
ClothVertex *verts = NULL;
float tnull[3] = {0,0,0};
- int cache_there = 0;
Cloth *cloth = NULL;
// If we have a clothObject, free it.
@@ -926,21 +789,6 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
cloth_from_mesh ( ob, clmd, dm );
- if((clmd->sim_parms->firstcachedframe < 0.0) || ((clmd->sim_parms->firstcachedframe >= 0.0) && (!cloth_read_cache(ob, clmd, clmd->sim_parms->firstcachedframe))))
- {
- // no cache there
- cache_there = 0;
- if(G.rt > 0)
- printf("cache_there = 0\n");
- }
- else
- {
- // we have a cache
- cache_there = 1;
- if(G.rt > 0)
- printf("cache_there = 1, fcf: %d\n", clmd->sim_parms->firstcachedframe);
- }
-
// create springs
clmd->clothObject->springs = NULL;
clmd->clothObject->numsprings = -1;
@@ -951,7 +799,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
// set initial values
for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ )
{
- if(!cache_there)
+ if(first)
{
VECCOPY ( verts->x, mvert[i].co );
Mat4MulVecfl ( ob->obmat, verts->x );
@@ -998,10 +846,11 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
}
// init our solver
- if ( solvers [clmd->sim_parms->solver_type].init )
+ if ( solvers [clmd->sim_parms->solver_type].init ) {
solvers [clmd->sim_parms->solver_type].init ( ob, clmd );
+ }
- if(cache_there)
+ if(!first)
implicit_set_positions(clmd);
clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon );
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 5f95ce61aca..ab6cf070a80 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -74,6 +74,7 @@
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_utildefines.h"
#include "BKE_scene.h"
@@ -1647,6 +1648,7 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
ob= node->ob;
if(ob && (ob->recalc & OB_RECALC)) {
all_layer= ob->lay;
+
/* got an object node that changes, now check relations */
for(itA = node->child; itA; itA= itA->next) {
all_layer |= itA->lay;
@@ -1720,18 +1722,24 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
}
/* node was checked to have lasttime != curtime , and is of type ID_OB */
-static unsigned int flush_layer_node(DagNode *node, int curtime)
+static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
{
+ Base *base;
DagAdjList *itA;
node->lasttime= curtime;
- node->lay= ((Object *)node->ob)->lay;
+ node->lay= 0;
+ for(base= sce->base.first; base; base= base->next) {
+ if(node->ob == base->object) {
+ node->lay= ((Object *)node->ob)->lay;
+ break;
+ }
+ }
for(itA = node->child; itA; itA= itA->next) {
if(itA->node->type==ID_OB) {
if(itA->node->lasttime!=curtime) {
- itA->lay= flush_layer_node(itA->node, curtime); // lay is only set once for each relation
- //printf("layer %d for relation %s to %s\n", itA->lay, ((Object *)node->ob)->id.name, ((Object *)itA->node->ob)->id.name);
+ itA->lay= flush_layer_node(sce, itA->node, curtime); // lay is only set once for each relation
}
else itA->lay= itA->node->lay;
@@ -1742,11 +1750,32 @@ static unsigned int flush_layer_node(DagNode *node, int curtime)
return node->lay;
}
+/* node was checked to have lasttime != curtime , and is of type ID_OB */
+static void flush_pointcache_reset(DagNode *node, int curtime)
+{
+ DagAdjList *itA;
+ Object *ob;
+
+ node->lasttime= curtime;
+
+ for(itA = node->child; itA; itA= itA->next) {
+ if(itA->node->type==ID_OB) {
+ if(itA->node->lasttime!=curtime) {
+ ob= (Object*)(node->ob);
+ if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH))
+ ob->recalc |= OB_RECALC_DATA;
+ flush_pointcache_reset(itA->node, curtime);
+ }
+ }
+ }
+}
+
/* flushes all recalc flags in objects down the dependency tree */
-void DAG_scene_flush_update(Scene *sce, unsigned int lay)
+void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
{
DagNode *firstnode;
DagAdjList *itA;
+ Object *ob;
int lasttime;
if(sce->theDag==NULL) {
@@ -1755,21 +1784,37 @@ void DAG_scene_flush_update(Scene *sce, unsigned int lay)
}
firstnode= sce->theDag->DagNode.first; // always scene node
+
+ for(itA = firstnode->child; itA; itA= itA->next)
+ itA->lay= 0;
/* first we flush the layer flags */
sce->theDag->time++; // so we know which nodes were accessed
lasttime= sce->theDag->time;
- for(itA = firstnode->child; itA; itA= itA->next) {
+
+ for(itA = firstnode->child; itA; itA= itA->next)
if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB)
- flush_layer_node(itA->node, lasttime);
- }
+ flush_layer_node(sce, itA->node, lasttime);
/* then we use the relationships + layer info to flush update events */
sce->theDag->time++; // so we know which nodes were accessed
lasttime= sce->theDag->time;
- for(itA = firstnode->child; itA; itA= itA->next) {
- if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB)
+ for(itA = firstnode->child; itA; itA= itA->next)
+ if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB)
flush_update_node(itA->node, lay, lasttime);
+
+ /* if update is not due to time change, do pointcache clears */
+ if(!time) {
+ sce->theDag->time++; // so we know which nodes were accessed
+ lasttime= sce->theDag->time;
+ for(itA = firstnode->child; itA; itA= itA->next) {
+ if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB) {
+ ob= (Object*)(itA->node->ob);
+ if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH))
+ ob->recalc |= OB_RECALC_DATA;
+ flush_pointcache_reset(itA->node, lasttime);
+ }
+ }
}
}
@@ -1955,7 +2000,7 @@ void DAG_scene_update_flags(Scene *scene, unsigned int lay)
}
for(sce= scene; sce; sce= sce->set)
- DAG_scene_flush_update(sce, lay);
+ DAG_scene_flush_update(sce, lay, 1);
/* test: set time flag, to disable baked systems to update */
for(SETLOOPER(scene, base)) {
@@ -2005,7 +2050,9 @@ void DAG_object_flush_update(Scene *sce, Object *ob, short flag)
{
if(ob==NULL || sce->theDag==NULL) return;
+
ob->recalc |= flag;
+ BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH);
/* all users of this ob->data should be checked */
/* BUT! displists for curves are still only on cu */
@@ -2018,8 +2065,9 @@ void DAG_object_flush_update(Scene *sce, Object *ob, short flag)
else {
Object *obt;
for (obt=G.main->object.first; obt; obt= obt->id.next) {
- if (obt->data==ob->data) {
+ if (obt != ob && obt->data==ob->data) {
obt->recalc |= OB_RECALC_DATA;
+ BKE_ptcache_object_reset(obt, PTCACHE_RESET_DEPSGRAPH);
}
}
}
@@ -2028,9 +2076,9 @@ void DAG_object_flush_update(Scene *sce, Object *ob, short flag)
}
if(G.curscreen)
- DAG_scene_flush_update(sce, dag_screen_view3d_layers());
+ DAG_scene_flush_update(sce, dag_screen_view3d_layers(), 0);
else
- DAG_scene_flush_update(sce, sce->lay);
+ DAG_scene_flush_update(sce, sce->lay, 0);
}
/* recursively descends tree, each node only checked once */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 2d609811efe..0f51c74c248 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -3453,7 +3453,7 @@ static DerivedMesh *decimateModifier_applyModifier(
if(numTris<3) {
modifier_setError(md,
- "There must be more than 3 input faces (triangles).");
+ "Modifier requires more than 3 input faces (triangles).");
goto exit;
}
@@ -5057,9 +5057,10 @@ static void clothModifier_initData(ModifierData *md)
clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
+ clmd->point_cache = BKE_ptcache_add();
/* check for alloc failing */
- if(!clmd->sim_parms || !clmd->coll_parms)
+ if(!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
return;
cloth_init (clmd);
@@ -5138,11 +5139,9 @@ static void clothModifier_copyData(ModifierData *md, ModifierData *target)
tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
-
- tclmd->sim_parms->lastcachedframe = 0;
+ tclmd->point_cache = BKE_ptcache_copy(clmd->point_cache);
}
-
static int clothModifier_dependsOnTime(ModifierData *md)
{
return 1;
@@ -5163,6 +5162,8 @@ static void clothModifier_freeData(ModifierData *md)
MEM_freeN(clmd->sim_parms);
if(clmd->coll_parms)
MEM_freeN(clmd->coll_parms);
+ if(clmd->point_cache)
+ BKE_ptcache_free(clmd->point_cache);
}
}
@@ -5435,7 +5436,6 @@ static void particleSystemModifier_freeData(ModifierData *md)
psmd->dm=0;
}
- psmd->psys->flag &= ~PSYS_ENABLED;
psmd->psys->flag |= PSYS_DELETE;
}
static void particleSystemModifier_copyData(ModifierData *md, ModifierData *target)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 287708a8ed4..ff5dcb763f4 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -105,6 +105,7 @@
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_property.h"
#include "BKE_sca.h"
#include "BKE_scene.h"
@@ -295,6 +296,7 @@ void unlink_object(Object *ob)
Camera *camera;
bConstraint *con;
bActionStrip *strip;
+ ModifierData *md;
int a;
unlink_controllers(&ob->controllers);
@@ -397,6 +399,11 @@ void unlink_object(Object *ob)
obt->recalc |= OB_RECALC_DATA;
else if(obt->soft)
obt->recalc |= OB_RECALC_DATA;
+
+ /* cloth */
+ for(md=obt->modifiers.first; md; md=md->next)
+ if(md->type == eModifierType_Cloth)
+ obt->recalc |= OB_RECALC_DATA;
}
/* strips */
@@ -1011,12 +1018,14 @@ SoftBody *copy_softbody(SoftBody *sb)
sbn->totspring= sbn->totpoint= 0;
sbn->bpoint= NULL;
sbn->bspring= NULL;
- sbn->ctime= 0.0f;
sbn->keys= NULL;
sbn->totkey= sbn->totpointkey= 0;
sbn->scratch= NULL;
+
+ sbn->pointcache= BKE_ptcache_copy(sb->pointcache);
+
return sbn;
}
@@ -1047,6 +1056,8 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys)
psysn->edit= NULL;
psysn->effectors.first= psysn->effectors.last= 0;
+ psysn->pointcache= BKE_ptcache_copy(psys->pointcache);
+
id_us_plus((ID *)psysn->part);
return psysn;
@@ -2180,7 +2191,7 @@ void object_handle_update(Object *ob)
if(ob->recalc & OB_RECALC) {
if(ob->recalc & OB_RECALC_OB) {
-
+
// printf("recalcob %s\n", ob->id.name+2);
/* handle proxy copy for target */
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 6b2f2f911c6..6bdb4e6f8d3 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -78,6 +78,7 @@
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_pointcache.h"
#include "blendef.h"
#include "RE_render_ext.h"
@@ -226,14 +227,14 @@ void psys_disable_all(Object *ob)
ParticleSystem *psys=ob->particlesystem.first;
for(; psys; psys=psys->next)
- psys->flag &= ~PSYS_ENABLED;
+ psys->flag |= PSYS_DISABLED;
}
void psys_enable_all(Object *ob)
{
ParticleSystem *psys=ob->particlesystem.first;
for(; psys; psys=psys->next)
- psys->flag |= PSYS_ENABLED;
+ psys->flag &= ~PSYS_DISABLED;
}
int psys_ob_has_hair(Object *ob)
{
@@ -253,7 +254,7 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd;
- if(!(psys->flag & PSYS_ENABLED))
+ if(psys->flag & PSYS_DISABLED)
return 0;
psmd= psys_get_modifier(ob, psys);
@@ -370,6 +371,9 @@ void psys_free(Object *ob, ParticleSystem * psys)
}
MEM_freeN(psys);
+
+ if(psys->pointcache)
+ BKE_ptcache_free(psys->pointcache);
}
}
@@ -2251,7 +2255,7 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed
int i, totchild, totparent, totthread;
unsigned long totchildstep;
- pthreads= psys_threads_create(ob, psys, G.scene->r.threads);
+ pthreads= psys_threads_create(ob, psys);
if(!psys_threads_init_path(pthreads, cfra, editupdate)) {
psys_threads_free(pthreads);
@@ -3080,6 +3084,42 @@ void psys_flush_settings(ParticleSettings *part, int event, int hair_recalc)
}
}
}
+
+LinkNode *psys_using_settings(ParticleSettings *part, int flush_update)
+{
+ Object *ob, *tob;
+ ParticleSystem *psys, *tpsys;
+ LinkNode *node= NULL;
+ int found;
+
+ /* update all that have same particle settings */
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ found= 0;
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ if(psys->part == part) {
+ BLI_linklist_append(&node, psys);
+ found++;
+ }
+ else if(psys->part->type == PART_REACTOR){
+ tob= (psys->target_ob)? psys->target_ob: ob;
+ tpsys= BLI_findlink(&tob->particlesystem, psys->target_psys-1);
+
+ if(tpsys && tpsys->part==part) {
+ BLI_linklist_append(&node, tpsys);
+ found++;
+ }
+ }
+ }
+
+ if(flush_update && found)
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+
+ return node;
+}
+
+
/************************************************/
/* Textures */
/************************************************/
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 8bde0afb752..cd0d6b5d113 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -121,7 +121,48 @@ static int get_current_display_percentage(ParticleSystem *psys)
return psys->part->disp;
}
-static void alloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
+void psys_reset(ParticleSystem *psys, int mode)
+{
+ ParticleSettings *part= psys->part;
+ ParticleData *pa;
+ int i;
+
+ if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) {
+ if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->flag & PSYS_EDITED))) {
+ if(psys->particles) {
+ if(psys->particles->keys)
+ MEM_freeN(psys->particles->keys);
+
+ for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++)
+ if(pa->hair) MEM_freeN(pa->hair);
+
+ MEM_freeN(psys->particles);
+ psys->particles= NULL;
+ }
+
+ psys->totpart= 0;
+ psys->totkeyed= 0;
+ psys->flag &= ~(PSYS_HAIR_DONE|PSYS_KEYED);
+ }
+ }
+
+ /* reset children */
+ if(psys->child) {
+ MEM_freeN(psys->child);
+ psys->child= 0;
+ }
+
+ psys->totchild= 0;
+
+ /* reset path cache */
+ psys_free_path_cache(psys);
+
+ /* reset point cache */
+ psys->pointcache->flag &= ~PTCACHE_SIMULATION_VALID;
+ psys->pointcache->simframe= 0;
+}
+
+static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
{
ParticleData *newpars = 0, *pa;
int i, totpart, totsaved = 0;
@@ -145,6 +186,12 @@ static void alloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
if(totsaved)
memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData));
+ if(psys->particles->keys)
+ MEM_freeN(psys->particles->keys);
+
+ for(i=0, pa=psys->particles; i<totsaved; i++, pa++)
+ if(pa->keys) pa->keys= NULL;
+
for(i=totsaved, pa=psys->particles+totsaved; i<psys->totpart; i++, pa++)
if(pa->hair) MEM_freeN(pa->hair);
@@ -1313,7 +1360,7 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Object *ob, Particl
ParticleThreadContext *ctx;
int i, totthread;
- pthreads= psys_threads_create(ob, psys, G.scene->r.threads);
+ pthreads= psys_threads_create(ob, psys);
if(!psys_threads_init_distribution(pthreads, finaldm, from)) {
psys_threads_free(pthreads);
@@ -1385,11 +1432,16 @@ static void distribute_particles(Object *ob, ParticleSystem *psys, int from)
}
/* threaded child particle distribution and path caching */
-ParticleThread *psys_threads_create(struct Object *ob, struct ParticleSystem *psys, int totthread)
+ParticleThread *psys_threads_create(struct Object *ob, struct ParticleSystem *psys)
{
ParticleThread *threads;
ParticleThreadContext *ctx;
- int i;
+ int i, totthread;
+
+ if(G.scene->r.mode & R_FIXED_THREADS)
+ totthread= G.scene->r.threads;
+ else
+ totthread= BLI_system_thread_count();
threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread");
ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext");
@@ -1922,7 +1974,8 @@ int psys_count_keyed_targets(Object *ob, ParticleSystem *psys)
BLI_freelistN(&lb);
return select;
}
-void set_keyed_keys(Object *ob, ParticleSystem *psys)
+
+static void set_keyed_keys(Object *ob, ParticleSystem *psys)
{
Object *kob = ob;
ParticleSystem *kpsys = psys;
@@ -1932,17 +1985,16 @@ void set_keyed_keys(Object *ob, ParticleSystem *psys)
float prevtime, nexttime, keyedtime;
/* no proper targets so let's clear and bail out */
- if(psys->totkeyed==0){
+ if(psys->totkeyed==0) {
free_keyed_keys(psys);
psys->flag &= ~PSYS_KEYED;
return;
}
- if(totpart && psys->particles->totkey != totkeys){
+ if(totpart && psys->particles->totkey != totkeys) {
free_keyed_keys(psys);
- psys->particles->keys = MEM_callocN(psys->totpart * totkeys * sizeof(ParticleKey),"Keyed keys");
-
+ psys->particles->keys = MEM_callocN(psys->totpart*totkeys*sizeof(ParticleKey), "Keyed keys");
psys->particles->totkey = totkeys;
for(i=1, pa=psys->particles+1; i<totpart; i++,pa++){
@@ -1954,9 +2006,10 @@ void set_keyed_keys(Object *ob, ParticleSystem *psys)
psys->flag &= ~PSYS_KEYED;
state.time=-1.0;
- for(k=0; k<totkeys; k++){
- for(i=0,pa=psys->particles; i<totpart; i++, pa++){
- psys_get_particle_state(kob, kpsys, i%kpsys->totpart, pa->keys + k, 1);
+ for(k=0; k<totkeys; k++) {
+ for(i=0,pa=psys->particles; i<totpart; i++, pa++) {
+ if(kpsys->totpart > 0)
+ psys_get_particle_state(kob, kpsys, i%kpsys->totpart, pa->keys + k, 1);
if(k==0)
pa->keys->time = pa->time;
@@ -2097,60 +2150,57 @@ void psys_get_reactor_target(Object *ob, ParticleSystem *psys, Object **target_o
/************************************************/
/* Point Cache */
/************************************************/
-void clear_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
-{
- ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
- int stack_index = modifiers_indexInObject(ob,(ModifierData*)psmd);
-
- BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_ALL, cfra, stack_index);
- /* reactors need to initialize particles always since their birth times might have changed */
- if(psys && psys->part && psys->part->type == PART_REACTOR)
- psys->recalc |= PSYS_INIT;
-}
static void write_particles_to_cache(Object *ob, ParticleSystem *psys, int cfra)
{
- FILE *fp = NULL;
- ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
+ PTCacheID pid;
+ PTCacheFile *pf;
ParticleData *pa;
- int stack_index = modifiers_indexInObject(ob,(ModifierData*)psmd);
- int i, totpart = psys->totpart;
+ int i, totpart= psys->totpart;
- if(totpart == 0) return;
+ if(totpart == 0)
+ return;
- fp = BKE_ptcache_id_fopen((ID *)ob, 'w', cfra, stack_index);
- if(!fp) return;
+ BKE_ptcache_id_from_particles(&pid, ob, psys);
+ pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, cfra);
+ if(!pf)
+ return;
+ /* assuming struct consists of tightly packed floats */
for(i=0, pa=psys->particles; i<totpart; i++, pa++)
- fwrite(&pa->state, sizeof(ParticleKey), 1, fp);
+ BKE_ptcache_file_write_floats(pf, (float*)&pa->state, sizeof(ParticleKey)/sizeof(float));
- fclose(fp);
+ BKE_ptcache_file_close(pf);
}
+
static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
{
- FILE *fp = NULL;
- ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
+ PTCacheID pid;
+ PTCacheFile *pf;
ParticleData *pa;
- int stack_index = modifiers_indexInObject(ob,(ModifierData*)psmd);
- int i, totpart = psys->totpart, ret = 1;
+ int i, totpart= psys->totpart;
- if(totpart == 0) return 0;
+ if(totpart == 0)
+ return 0;
- fp = BKE_ptcache_id_fopen((ID *)ob, 'r', cfra, stack_index);
- if(!fp)
- ret = 0;
- else {
- for(i=0, pa=psys->particles; i<totpart; i++, pa++)
- if((fread(&pa->state, sizeof(ParticleKey), 1, fp)) != 1) {
- ret = 0;
- break;
- }
-
- fclose(fp);
+ BKE_ptcache_id_from_particles(&pid, ob, psys);
+ pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, cfra);
+ if(!pf)
+ return 0;
+
+ /* assuming struct consists of tightly packed floats */
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
+ if(!BKE_ptcache_file_read_floats(pf, (float*)&pa->state, sizeof(ParticleKey)/sizeof(float))) {
+ BKE_ptcache_file_close(pf);
+ return 0;
+ }
}
- return ret;
+ BKE_ptcache_file_close(pf);
+
+ return 1;
}
+
/************************************************/
/* Effectors */
/************************************************/
@@ -4203,7 +4253,7 @@ static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifi
copy_particle_key(key,&pa->state,1);
}
- if(dfra>0.0 || psys->recalc){
+ if(1) {
if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0)
react_to_events(psys,p);
@@ -4306,7 +4356,7 @@ static void psys_update_path_cache(Object *ob, ParticleSystemModifierData *psmd,
if(distr){
if(alloc)
- alloc_particles(ob,psys,psys->totpart);
+ realloc_particles(ob,psys,psys->totpart);
if(get_psys_tot_child(psys)) {
/* don't generate children while computing the hair keys */
@@ -4366,7 +4416,7 @@ static void hair_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSyst
}
/* updates cached particles' alive & other flags etc..*/
-static void cached_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra, float *vg_size)
+static void cached_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
{
ParticleSettings *part=psys->part;
ParticleData *pa;
@@ -4374,7 +4424,10 @@ static void cached_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSy
IpoCurve *icu_esize=find_ipocurve(part->ipo,PART_EMIT_SIZE);
Material *ma=give_current_material(ob,part->omat);
int p;
- float ipotime=cfra, disp, birthtime, dietime;
+ float ipotime=cfra, disp, birthtime, dietime, *vg_size= NULL;
+
+ if(part->from!=PART_FROM_PARTICLE)
+ vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
if(psys->effectors.first)
psys_end_effectors(psys);
@@ -4437,10 +4490,48 @@ static void cached_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSy
/* make sure that children are up to date */
if(psys->part->childtype && psys->totchild != get_psys_tot_child(psys)) {
- alloc_particles(ob, psys, psys->totpart);
+ realloc_particles(ob, psys, psys->totpart);
distribute_particles(ob, psys, PART_FROM_CHILD);
}
+
+ if(vg_size)
+ MEM_freeN(vg_size);
}
+
+void psys_changed_type(ParticleSystem *psys)
+{
+ ParticleSettings *part;
+
+ part= psys->part;
+
+ /* system type has changed so set sensible defaults and clear non applicable flags */
+ if(part->from == PART_FROM_PARTICLE) {
+ if(part->type != PART_REACTOR)
+ part->from = PART_FROM_FACE;
+ if(part->distr == PART_DISTR_GRID)
+ part->distr = PART_DISTR_JIT;
+ }
+
+ if(psys->part->phystype != PART_PHYS_KEYED)
+ psys->flag &= ~PSYS_KEYED;
+
+ if(part->type == PART_HAIR) {
+ part->draw_as = PART_DRAW_PATH;
+ part->rotfrom = PART_ROT_IINCR;
+ }
+ else {
+ free_hair(psys, 1);
+
+ if(part->draw_as == PART_DRAW_PATH)
+ if(psys->part->phystype != PART_PHYS_KEYED)
+ part->draw_as = PART_DRAW_DOT;
+ }
+
+ psys->softflag= 0;
+
+ psys_reset(psys, PSYS_RESET_ALL);
+}
+
static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra)
{
if(psys->particles){
@@ -4448,6 +4539,7 @@ static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra)
psys->particles = 0;
psys->totpart = 0;
}
+
/* fluid sim particle import handling, actual loading of particles from file */
#ifndef DISABLE_ELBEEM
if( (1) && (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && // broken, disabled for now!
@@ -4488,7 +4580,7 @@ static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra)
part->lifetime = G.scene->r.efra + 1;
/* initialize particles */
- alloc_particles(ob, psys, part->totpart);
+ realloc_particles(ob, psys, part->totpart);
initialize_all_particles(ob, psys, 0);
// set up reading mask
@@ -4496,8 +4588,7 @@ static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra)
for(p=0, pa=psys->particles; p<totpart; p++, pa++) {
int ptype=0;
- short shsize=0;
- float convertSize=0.0;
+
gzread(gzf, &ptype, sizeof( ptype ));
if(ptype&readMask) {
activeParts++;
@@ -4540,113 +4631,107 @@ static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra)
} // fluid sim particles done
#endif // DISABLE_ELBEEM
}
+
/* Calculates the next state for all particles of the system */
/* In particles code most fra-ending are frames, time-ending are fra*timestep (seconds)*/
static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
{
ParticleSettings *part;
ParticleData *pa;
- int totpart,oldtotpart=0,p;
- float disp, *vg_vel=0, *vg_tan=0, *vg_rot=0, *vg_size=0;
- int init=0,distr=0,alloc=0;
+ PointCache *cache;
+ PTCacheID pid;
+ int totpart, oldtotpart, totchild, oldtotchild, p;
+ float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0;
+ int init= 0, distr= 0, alloc= 0, usecache= 0;
+ int framenr, framedelta, startframe, endframe;
- /*----start validity checks----*/
+ part= psys->part;
+ cache= psys->pointcache;
- part=psys->part;
+ framenr= (int)CFRA;
+ framedelta= framenr - cache->simframe;
- if(part->flag&PART_ABS_TIME && part->ipo){
+ BKE_ptcache_id_from_particles(&pid, ob, psys);
+ BKE_ptcache_id_time(&pid, 0.0f, &startframe, &endframe, NULL);
+
+ /* update ipo's */
+ if((part->flag & PART_ABS_TIME) && part->ipo) {
calc_ipo(part->ipo, cfra);
execute_ipo((ID *)part, part->ipo);
}
- if(part->from!=PART_FROM_PARTICLE && part->type!=PART_FLUID)
- vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
-
- if(part->type == PART_HAIR) {
- if(psys->flag & PSYS_HAIR_DONE) {
- hair_step(ob, psmd, psys, cfra);
- psys->cfra = cfra;
- psys->recalc = 0;
- return;
- }
+ /* hair if it's already done is handled separate */
+ if(part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DONE)) {
+ hair_step(ob, psmd, psys, cfra);
+ psys->cfra = cfra;
+ psys->recalc = 0;
+ return;
}
+ /* fluid is also handled separate */
else if(part->type == PART_FLUID) {
- particles_fluid_step(ob, psys, (int)cfra);
+ particles_fluid_step(ob, psys, framenr);
psys->cfra = cfra;
psys->recalc = 0;
return;
}
- else if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED))
- ; /* cache shouldn't be used for "none" or "keyed" physics */
- else {
- if(psys->recalc && (psys->flag & PSYS_PROTECT_CACHE) == 0)
- clear_particles_from_cache(ob,psys,(int)cfra);
- else if(get_particles_from_cache(ob, psys, (int)cfra)) {
- cached_step(ob,psmd,psys,cfra,vg_size);
- psys->cfra=cfra;
- psys->recalc = 0;
- return;
- }
- }
- /* if still here react to events */
+ /* cache shouldn't be used for hair or "none" or "first keyed" physics */
+ if(part->type == PART_HAIR || part->phystype == PART_PHYS_NO)
+ usecache= 0;
+ else if(part->type == PART_PHYS_KEYED && (psys->flag & PSYS_FIRST_KEYED))
+ usecache= 0;
+ else if(BKE_ptcache_get_continue_physics())
+ usecache= 0;
+ else
+ usecache= 1;
- if(psys->recalc&PSYS_TYPE) {
- /* system type has changed so set sensible defaults and clear non applicable flags */
- if(part->from == PART_FROM_PARTICLE) {
- if(part->type != PART_REACTOR)
- part->from = PART_FROM_FACE;
- if(part->distr == PART_DISTR_GRID)
- part->distr = PART_DISTR_JIT;
+ if(usecache) {
+ /* frame clamping */
+ if(framenr < startframe) {
+ psys_reset(psys, PSYS_RESET_DEPSGRAPH);
+ psys->cfra = cfra;
+ psys->recalc = 0;
+ return;
}
-
- if(psys->part->phystype != PART_PHYS_KEYED)
- psys->flag &= ~PSYS_KEYED;
-
- if(part->type == PART_HAIR) {
- part->draw_as = PART_DRAW_PATH;
- part->rotfrom = PART_ROT_IINCR;
+ else if(framenr > endframe) {
+ framenr= endframe;
}
- else
- free_hair(psys, 1);
-
- psys->softflag= 0;
- psys->recalc &= ~PSYS_TYPE;
- alloc = 1;
-
- /* this is a bad level call, but currently type change
- * can happen after redraw, so force redraw from here */
- allqueue(REDRAWBUTSOBJECT, 0);
}
- else
- oldtotpart = psys->totpart;
+
+ /* verify if we need to reallocate */
+ oldtotpart = psys->totpart;
+ oldtotchild = psys->totchild;
if(part->distr == PART_DISTR_GRID)
- totpart = part->grid_res * part->grid_res * part->grid_res;
+ totpart = part->grid_res*part->grid_res*part->grid_res;
else
totpart = psys->part->totpart;
+ totchild = get_psys_tot_child(psys);
- if(oldtotpart != totpart || psys->recalc&PSYS_ALLOC || (psys->part->childtype && psys->totchild != get_psys_tot_child(psys)))
+ if(oldtotpart != totpart || (psys->part->childtype && oldtotchild != totchild)) {
+ realloc_particles(ob, psys, totpart);
alloc = 1;
+ distr= 1;
+ init= 1;
+ }
- if(alloc || psys->recalc&PSYS_DISTR || (psys->vgroup[PSYS_VG_DENSITY] && (G.f & G_WEIGHTPAINT) && ob==OBACT))
- distr = 1;
-
- if(distr || psys->recalc&PSYS_INIT)
- init = 1;
+ if(psys->recalc & PSYS_DISTR) {
+ distr= 1;
+ init= 1;
+ }
if(init) {
if(distr) {
if(alloc)
- alloc_particles(ob, psys, totpart);
+ realloc_particles(ob, psys, totpart);
distribute_particles(ob, psys, part->from);
if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE))
- /* don't generate children while growing hair - waste of time */
- psys_free_children(psys);
- else if(get_psys_tot_child(psys))
- distribute_particles(ob, psys, PART_FROM_CHILD);
+ /* don't generate children while growing hair - waste of time */
+ psys_free_children(psys);
+ else if(get_psys_tot_child(psys))
+ distribute_particles(ob, psys, PART_FROM_CHILD);
}
initialize_all_particles(ob, psys, psmd);
@@ -4657,17 +4742,59 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
psmd->flag |= eParticleSystemFlag_Pars;
}
+ /* try to read from the cache */
+ if(usecache) {
+ if(get_particles_from_cache(ob, psys, framenr)) {
+ if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
+ psys_count_keyed_targets(ob,psys);
+ set_keyed_keys(ob, psys);
+ }
+
+ cached_step(ob,psmd,psys,cfra);
+ psys->cfra=cfra;
+ psys->recalc = 0;
+
+ if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
+ psys_update_path_cache(ob,psmd,psys,framenr);
+ }
+
+ return;
+ }
+ else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
+ psys_reset(psys, PSYS_RESET_DEPSGRAPH);
+ psys->cfra=cfra;
+ psys->recalc = 0;
+ return;
+ }
+
+ if(framenr != startframe && framedelta != 1) {
+ psys_reset(psys, PSYS_RESET_DEPSGRAPH);
+ psys->cfra = cfra;
+ psys->recalc = 0;
+ return;
+ }
+ }
+ else {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ }
+
+ /* if on second frame, write cache for first frame */
+ if(usecache && framenr == startframe+1)
+ write_particles_to_cache(ob, psys, startframe);
if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED)
psys_count_keyed_targets(ob,psys);
- if(part->from!=PART_FROM_PARTICLE){
- vg_vel=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_VEL);
- vg_tan=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN);
- vg_rot=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT);
+ /* initialize vertex groups */
+ if(part->from!=PART_FROM_PARTICLE) {
+ vg_vel= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_VEL);
+ vg_tan= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN);
+ vg_rot= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT);
+ vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
}
- /* set particles to be not calculated */
+ /* set particles to be not calculated TODO: can't work with pointcache */
disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
for(p=0, pa=psys->particles; p<totpart; p++,pa++){
@@ -4680,15 +4807,16 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
/* ok now we're all set so let's go */
if(psys->totpart)
dynamics_step(ob,psys,psmd,cfra,vg_vel,vg_tan,vg_rot,vg_size);
+
+ cache->simframe= framenr;
+ cache->flag |= PTCACHE_SIMULATION_VALID;
psys->recalc = 0;
psys->cfra = cfra;
- if(part->type == PART_HAIR || part->phystype == PART_PHYS_NO
- || (part->phystype == PART_PHYS_KEYED && psys->flag & PSYS_FIRST_KEYED))
- ; /* cache shouldn't be used for hair or "none" or "first keyed" physics */
- else
- write_particles_to_cache(ob, psys, cfra);
+ /* only write cache starting from second frame */
+ if(usecache && framenr != startframe)
+ write_particles_to_cache(ob, psys, framenr);
/* for keyed particles the path is allways known so it can be drawn */
if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED){
@@ -4698,9 +4826,11 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
else if(psys->pathcache)
psys_free_path_cache(psys);
+ /* cleanup */
if(vg_vel) MEM_freeN(vg_vel);
if(vg_tan) MEM_freeN(vg_tan);
if(vg_rot) MEM_freeN(vg_rot);
+ if(vg_size) MEM_freeN(vg_size);
if(psys->lattice){
end_latt_deform();
@@ -4708,106 +4838,97 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
}
}
-void psys_to_softbody(Object *ob, ParticleSystem *psys, int force_recalc)
+void psys_to_softbody(Object *ob, ParticleSystem *psys)
{
SoftBody *sb;
short softflag;
- if((psys->softflag&OB_SB_ENABLE)==0) return;
-
- if(psys->recalc || force_recalc)
- psys->softflag|=OB_SB_REDO;
+ if(!(psys->softflag & OB_SB_ENABLE))
+ return;
/* let's replace the object's own softbody with the particle softbody */
/* a temporary solution before cloth simulation is implemented, jahka */
/* save these */
- sb=ob->soft;
- softflag=ob->softflag;
+ sb= ob->soft;
+ softflag= ob->softflag;
/* swich to new ones */
- ob->soft=psys->soft;
- ob->softflag=psys->softflag;
+ ob->soft= psys->soft;
+ ob->softflag= psys->softflag;
/* do softbody */
sbObjectStep(ob, (float)G.scene->r.cfra, NULL, psys_count_keys(psys));
/* return things back to normal */
- psys->soft=ob->soft;
- psys->softflag=ob->softflag;
+ psys->soft= ob->soft;
+ psys->softflag= ob->softflag;
- ob->soft=sb;
- ob->softflag=softflag;
+ ob->soft= sb;
+ ob->softflag= softflag;
}
+
static int hair_needs_recalc(ParticleSystem *psys)
{
- if((psys->flag & PSYS_EDITED)==0 && (
- (psys->flag & PSYS_HAIR_DONE)==0
- || psys->recalc & PSYS_RECALC_HAIR)
- ) {
+ if((psys->flag & PSYS_EDITED)==0 &&
+ ((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_HAIR)) {
psys->recalc &= ~PSYS_RECALC_HAIR;
return 1;
}
return 0;
}
-/* main particle update call, checks that things are ok on the large scale before actual particle calculations */
-void particle_system_update(Object *ob, ParticleSystem *psys){
- ParticleSystemModifierData *psmd=0;
+/* main particle update call, checks that things are ok on the large scale before actual particle calculations */
+void particle_system_update(Object *ob, ParticleSystem *psys)
+{
+ ParticleSystemModifierData *psmd;
float cfra;
if(!psys_check_enabled(ob, psys))
return;
- cfra=bsystem_time(ob,(float)CFRA,0.0);
+ cfra= bsystem_time(ob, CFRA, 0.0f);
psmd= psys_get_modifier(ob, psys);
/* system was already updated from modifier stack */
- if(psmd->flag&eParticleSystemFlag_psys_updated) {
+ if(psmd->flag & eParticleSystemFlag_psys_updated) {
psmd->flag &= ~eParticleSystemFlag_psys_updated;
/* make sure it really was updated to cfra */
- if(psys->cfra==cfra)
+ if(psys->cfra == cfra)
return;
}
if(!psmd->dm)
return;
- /* baked path softbody */
- if(psys->part->type==PART_HAIR && psys->soft)
- psys_to_softbody(ob, psys, 0);
-
- /* not needed, this is all handled in hair_step */
- ///* is the mesh changing under the edited particles? */
- //if((psys->flag & PSYS_EDITED) && psys->part->type==PART_HAIR && psys->recalc & PSYS_RECALC_HAIR) {
- // /* Just update the particles on the mesh */
- // psys_update_edithair_dmfaces(ob, psmd->dm, psys);
- //}
-
- if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)){
+ /* (re-)create hair */
+ if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)) {
float hcfra=0.0f;
int i;
free_hair(psys, 0);
/* first step is negative so particles get killed and reset */
- psys->cfra=1.0f;
+ psys->cfra= 1.0f;
for(i=0; i<=psys->part->hair_step; i++){
hcfra=100.0f*(float)i/(float)psys->part->hair_step;
- system_step(ob,psys,psmd,hcfra);
- save_hair(ob,psys,psmd,hcfra);
+ system_step(ob, psys, psmd, hcfra);
+ save_hair(ob, psys, psmd, hcfra);
}
psys->flag |= PSYS_HAIR_DONE;
-
- if(psys->softflag&OB_SB_ENABLE)
- psys_to_softbody(ob,psys,1);
}
- system_step(ob,psys,psmd,cfra);
+ /* handle softbody hair */
+ if(psys->part->type==PART_HAIR && psys->soft)
+ psys_to_softbody(ob, psys);
+
+ /* the main particle system step */
+ system_step(ob, psys, psmd, cfra);
- Mat4Invert(psys->imat, ob->obmat); /* used for duplicators */
+ /* save matrix for duplicators */
+ Mat4Invert(psys->imat, ob->obmat);
}
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index cdb95e2f015..3b411e758c0 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -27,21 +27,36 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include "BKE_pointcache.h"
+#include "MEM_guardedalloc.h"
-#include "BKE_utildefines.h"
-#include "BKE_global.h"
-#include "BKE_library.h"
+#include "DNA_ID.h"
+#include "DNA_cloth_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
+
+#include "BKE_cloth.h"
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
+#include "BKE_softbody.h"
#include "BKE_utildefines.h"
+
#include "blendef.h"
/* needed for directory lookup */
@@ -58,19 +73,114 @@
#include <unistd.h>
#endif
+/* Creating ID's */
+
+void BKE_ptcache_id_from_softbody(PTCacheID *pid, Object *ob, SoftBody *sb)
+{
+ ParticleSystemModifierData *psmd;
+ ModifierData *md;
+ int a;
+
+ memset(pid, 0, sizeof(PTCacheID));
+
+ pid->ob= ob;
+ pid->data= sb;
+ pid->type= PTCACHE_TYPE_SOFTBODY;
+ pid->cache= sb->pointcache;
+
+ if(sb->particles) {
+ psmd= psys_get_modifier(ob, sb->particles);
+ pid->stack_index= modifiers_indexInObject(ob, (ModifierData*)psmd);
+ }
+ else {
+ for(a=0, md=ob->modifiers.first; md; md=md->next, a++) {
+ if(md->type == eModifierType_Softbody) {
+ pid->stack_index = a;
+ break;
+ }
+ }
+ }
+}
+
+void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *psys)
+{
+ ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
+
+ memset(pid, 0, sizeof(PTCacheID));
+
+ pid->ob= ob;
+ pid->data= psys;
+ pid->type= PTCACHE_TYPE_PARTICLES;
+ pid->stack_index= modifiers_indexInObject(ob, (ModifierData *)psmd);
+ pid->cache= psys->pointcache;
+}
+
+void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *clmd)
+{
+ memset(pid, 0, sizeof(PTCacheID));
+
+ pid->ob= ob;
+ pid->data= clmd;
+ pid->type= PTCACHE_TYPE_CLOTH;
+ pid->stack_index= modifiers_indexInObject(ob, (ModifierData *)clmd);
+ pid->cache= clmd->point_cache;
+}
+
+void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
+{
+ PTCacheID *pid;
+ ParticleSystem *psys;
+ ModifierData *md;
+
+ lb->first= lb->last= NULL;
+
+ if(ob->soft) {
+ pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
+ BKE_ptcache_id_from_softbody(pid, ob, ob->soft);
+ BLI_addtail(lb, pid);
+ }
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
+ BKE_ptcache_id_from_particles(pid, ob, psys);
+ BLI_addtail(lb, pid);
+
+ if(psys->soft) {
+ pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
+ BKE_ptcache_id_from_softbody(pid, ob, psys->soft);
+ BLI_addtail(lb, pid);
+ }
+ }
+
+ for(md=ob->modifiers.first; md; md=md->next) {
+ if(md->type == eModifierType_Cloth) {
+ pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
+ BKE_ptcache_id_from_cloth(pid, ob, (ClothModifierData*)md);
+ BLI_addtail(lb, pid);
+ }
+ }
+}
+
/* Takes an Object ID and returns a unique name
- id: object id
- cfra: frame for the cache, can be negative
- stack_index: index in the modifier stack. we can have cache for more then one stack_index
*/
-static int ptcache_path(char *filename)
+static int ptcache_path(PTCacheID *pid, char *filename)
{
+ Library *lib;
int i;
- if (G.relbase_valid) {
+
+ lib= (pid)? pid->ob->id.lib: NULL;
+
+ if (G.relbase_valid || lib) {
char dir[FILE_MAX], file[FILE_MAX]; /* we dont want the dir, only the file */
-
- BLI_split_dirfile(G.sce, dir, file);
+ char *blendfilename;
+
+ blendfilename= (lib)? lib->filename: G.sce;
+
+ BLI_split_dirfile(blendfilename, dir, file);
i = strlen(file);
/* remove .blend */
@@ -78,7 +188,7 @@ static int ptcache_path(char *filename)
file[i-6] = '\0';
sprintf(filename, "//"PTCACHE_PATH"%s/", file); /* add blend file name to pointcache dir */
- BLI_convertstringcode(filename, G.sce, 0);
+ BLI_convertstringcode(filename, blendfilename, 0);
return strlen(filename);
}
@@ -87,7 +197,7 @@ static int ptcache_path(char *filename)
return sprintf(filename, "%s"PTCACHE_PATH"%d/", btempdir, abs(getpid()));
}
-int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext)
+static int BKE_ptcache_id_filename(PTCacheID *pid, char *filename, int cfra, short do_path, short do_ext)
{
int len=0;
char *idname;
@@ -99,10 +209,10 @@ int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_i
/* start with temp dir */
if (do_path) {
- len = ptcache_path(filename);
+ len = ptcache_path(pid, filename);
newname += len;
}
- idname = (id->name+2);
+ idname = (pid->ob->id.name+2);
/* convert chars to hex so they are always a valid filename */
while('\0' != *idname) {
sprintf(newname, "%02X", (char)(*idname++));
@@ -111,7 +221,7 @@ int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_i
}
if (do_ext) {
- sprintf(newname, "_%06d_%02d"PTCACHE_EXT, cfra, stack_index); /* always 6 chars */
+ sprintf(newname, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
len += 16;
}
@@ -119,31 +229,53 @@ int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_i
}
/* youll need to close yourself after! */
-FILE *BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index)
+PTCacheFile *BKE_ptcache_file_open(PTCacheID *pid, int mode, int cfra)
{
- /* mode is same as fopen's modes */
+ PTCacheFile *pf;
FILE *fp = NULL;
char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
+ /* don't allow writing for linked objects */
+ if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE)
+ return NULL;
+
/*if (!G.relbase_valid) return NULL; *//* save blend file before using pointcache */
- BKE_ptcache_id_filename(id, filename, cfra, stack_index, 1, 1);
+ BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
- if (mode=='r') {
+ if (mode==PTCACHE_FILE_READ) {
if (!BLI_exists(filename)) {
return NULL;
}
fp = fopen(filename, "rb");
- } else if (mode=='w') {
+ } else if (mode==PTCACHE_FILE_WRITE) {
BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */
fp = fopen(filename, "wb");
}
- if (!fp) {
+ if (!fp)
return NULL;
- }
+
+ pf= MEM_mallocN(sizeof(PTCacheFile), "PTCacheFile");
+ pf->fp= fp;
- return fp;
+ return pf;
+}
+
+void BKE_ptcache_file_close(PTCacheFile *pf)
+{
+ fclose(pf->fp);
+ MEM_freeN(pf);
+}
+
+int BKE_ptcache_file_read_floats(PTCacheFile *pf, float *f, int tot)
+{
+ return (fread(f, sizeof(float), tot, pf->fp) == tot);
+}
+
+int BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot)
+{
+ return (fwrite(f, sizeof(float), tot, pf->fp) == tot);
}
/* youll need to close yourself after!
@@ -151,7 +283,7 @@ FILE *BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index)
*/
-void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index)
+void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
{
int len; /* store the length of the string */
@@ -161,7 +293,14 @@ void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index)
char path[FILE_MAX];
char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
char path_full[(FILE_MAXDIR+FILE_MAXFILE)*2];
-
+
+ if(!pid->cache)
+ return;
+
+ /* don't allow clearing for linked objects */
+ if(pid->ob->id.lib)
+ return;
+
/*if (!G.relbase_valid) return; *//* save blend file before using pointcache */
/* clear all files in the temp dir with the prefix of the ID and the ".bphys" suffix */
@@ -169,9 +308,9 @@ void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index)
case PTCACHE_CLEAR_ALL:
case PTCACHE_CLEAR_BEFORE:
case PTCACHE_CLEAR_AFTER:
- ptcache_path(path);
+ ptcache_path(pid, path);
- len = BKE_ptcache_id_filename(id, filename, cfra, stack_index, 0, 0); /* no path */
+ len = BKE_ptcache_id_filename(pid, filename, cfra, 0, 0); /* no path */
dir = opendir(path);
if (dir==NULL)
@@ -206,22 +345,149 @@ void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index)
break;
case PTCACHE_CLEAR_FRAME:
- len = BKE_ptcache_id_filename(id, filename, cfra, stack_index, 1, 1); /* no path */
+ len = BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); /* no path */
BLI_delete(filename, 0, 0);
break;
}
- return;
}
-int BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index)
+int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
{
char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
+
+ if(!pid->cache)
+ return 0;
- BKE_ptcache_id_filename(id, filename, cfra, stack_index, 1, 1);
+ BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
return BLI_exists(filename);
}
+void BKE_ptcache_id_time(PTCacheID *pid, float cfra, int *startframe, int *endframe, float *timescale)
+{
+ Object *ob;
+ PointCache *cache;
+ float offset, time, nexttime;
+
+ /* time handling for point cache:
+ * - simulation time is scaled by result of bsystem_time
+ * - for offsetting time only time offset is taken into account, since
+ * that's always the same and can't be animated. a timeoffset which
+ * varies over time is not simpe to support.
+ * - field and motion blur offsets are currently ignored, proper solution
+ * is probably to interpolate results from two frames for that ..
+ */
+
+ ob= pid->ob;
+ cache= pid->cache;
+
+ if(timescale) {
+ time= bsystem_time(ob, cfra, 0.0f);
+ nexttime= bsystem_time(ob, cfra+1.0f, 0.0f);
+
+ *timescale= MAX2(nexttime - time, 0.0f);
+ }
+
+ if(startframe && endframe) {
+ *startframe= cache->startframe;
+ *endframe= cache->endframe;
+
+ if ((ob->ipoflag & OB_OFFS_PARENT) && (ob->partype & PARSLOW)==0) {
+ offset= give_timeoffset(ob);
+
+ *startframe += (int)(offset+0.5f);
+ *endframe += (int)(offset+0.5f);
+ }
+ }
+}
+
+int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
+{
+ PointCache *cache;
+ int reset, clear;
+
+ if(!pid->cache)
+ return 0;
+
+ cache= pid->cache;
+ reset= 0;
+ clear= 0;
+
+ if(mode == PTCACHE_RESET_DEPSGRAPH) {
+ if(!(cache->flag & PTCACHE_BAKED) && !BKE_ptcache_get_continue_physics()) {
+ reset= 1;
+ clear= 1;
+ }
+ else
+ cache->flag |= PTCACHE_OUTDATED;
+ }
+ else if(mode == PTCACHE_RESET_BAKED) {
+ if(!BKE_ptcache_get_continue_physics()) {
+ reset= 1;
+ clear= 1;
+ }
+ else
+ cache->flag |= PTCACHE_OUTDATED;
+ }
+ else if(mode == PTCACHE_RESET_OUTDATED) {
+ reset = 1;
+
+ if(cache->flag & PTCACHE_OUTDATED)
+ if(!(cache->flag & PTCACHE_BAKED))
+ clear= 1;
+ }
+
+ if(reset) {
+ cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_SIMULATION_VALID);
+ cache->simframe= 0;
+
+ if(pid->type == PTCACHE_TYPE_CLOTH)
+ cloth_free_modifier(pid->ob, pid->data);
+ else if(pid->type == PTCACHE_TYPE_SOFTBODY)
+ sbFreeSimulation(pid->data);
+ else if(pid->type == PTCACHE_TYPE_PARTICLES)
+ psys_reset(pid->data, PSYS_RESET_DEPSGRAPH);
+ }
+ if(clear)
+ BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+
+ return (reset || clear);
+}
+
+int BKE_ptcache_object_reset(Object *ob, int mode)
+{
+ PTCacheID pid;
+ ParticleSystem *psys;
+ ModifierData *md;
+ int reset;
+
+ reset= 0;
+
+ if(ob->soft) {
+ BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
+ reset |= BKE_ptcache_id_reset(&pid, mode);
+ }
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ BKE_ptcache_id_from_particles(&pid, ob, psys);
+ reset |= BKE_ptcache_id_reset(&pid, mode);
+
+ if(psys->soft) {
+ BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
+ reset |= BKE_ptcache_id_reset(&pid, mode);
+ }
+ }
+
+ for(md=ob->modifiers.first; md; md=md->next) {
+ if(md->type == eModifierType_Cloth) {
+ BKE_ptcache_id_from_cloth(&pid, ob, (ClothModifierData*)md);
+ reset |= BKE_ptcache_id_reset(&pid, mode);
+ }
+ }
+
+ return reset;
+}
+
/* Use this when quitting blender, with unsaved files */
void BKE_ptcache_remove(void)
{
@@ -229,7 +495,7 @@ void BKE_ptcache_remove(void)
char path_full[FILE_MAX];
int rmdir = 1;
- ptcache_path(path);
+ ptcache_path(NULL, path);
if (BLI_exists(path)) {
/* TODO, Check with win32, probably needs last slash removed */
@@ -260,3 +526,58 @@ void BKE_ptcache_remove(void)
BLI_delete(path, 1, 0);
}
}
+
+/* Continuous Interaction */
+
+static int CONTINUE_PHYSICS = 0;
+
+void BKE_ptcache_set_continue_physics(int enable)
+{
+ Object *ob;
+
+ if(CONTINUE_PHYSICS != enable) {
+ CONTINUE_PHYSICS = enable;
+
+ if(CONTINUE_PHYSICS == 0) {
+ for(ob=G.main->object.first; ob; ob=ob->id.next)
+ if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_OUTDATED))
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+}
+
+int BKE_ptcache_get_continue_physics()
+{
+ return CONTINUE_PHYSICS;
+}
+
+/* Point Cache */
+
+PointCache *BKE_ptcache_add()
+{
+ PointCache *cache;
+
+ cache= MEM_callocN(sizeof(PointCache), "PointCache");
+ cache->startframe= 1;
+ cache->endframe= 250;
+
+ return cache;
+}
+
+void BKE_ptcache_free(PointCache *cache)
+{
+ MEM_freeN(cache);
+}
+
+PointCache *BKE_ptcache_copy(PointCache *cache)
+{
+ PointCache *ncache;
+
+ ncache= MEM_dupallocN(cache);
+
+ ncache->flag= 0;
+ ncache->simframe= 0;
+
+ return ncache;
+}
+
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index df6b0d37867..c7440f39a0c 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -3219,105 +3219,66 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts,
}
}
-void softbody_clear_cache(Object *ob, float framenr)
+void sbWriteCache(Object *ob, int framenr)
{
- SoftBody *sb = ob->soft;
- ModifierData *md = ob->modifiers.first;
- int stack_index = -1;
- int a;
-
- if(sb==NULL) return;
-
- if(sb->particles)
- stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,sb->particles));
- else {
- for(a=0; md; md=md->next, a++) {
- if(md->type == eModifierType_Softbody) {
- stack_index = a;
- break;
- }
- }
- }
-
- BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_ALL, framenr, stack_index);
-}
-static void softbody_write_cache(Object *ob, float framenr)
-{
- FILE *fp = NULL;
- SoftBody *sb = ob->soft;
+ SoftBody *sb= ob->soft;
BodyPoint *bp;
- ModifierData *md = ob->modifiers.first;
- int stack_index = -1;
+ PTCacheID pid;
+ PTCacheFile *pf;
int a;
- if(sb->totpoint == 0) return;
-
- if(sb->particles)
- stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,sb->particles));
- else {
- for(a=0; md; md=md->next, a++) {
- if(md->type == eModifierType_Softbody) {
- stack_index = a;
- break;
- }
- }
- }
-
- fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index);
- if(!fp) return;
+ if(sb->totpoint == 0)
+ return;
+ BKE_ptcache_id_from_softbody(&pid, ob, sb);
+ pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, framenr);
+ if(!pf)
+ return;
+
for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++)
- fwrite(&bp->pos, sizeof(float), 3, fp);
-/*write velocities too */
+ BKE_ptcache_file_write_floats(pf, bp->pos, 3);
+
for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++)
- fwrite(&bp->vec, sizeof(float), 3, fp);
-
- fclose(fp);
+ BKE_ptcache_file_write_floats(pf, bp->vec, 3);
+
+ BKE_ptcache_file_close(pf);
}
+
static int softbody_read_cache(Object *ob, float framenr)
{
- FILE *fp = NULL;
- SoftBody *sb = ob->soft;
+ SoftBody *sb= ob->soft;
BodyPoint *bp;
- ModifierData *md = ob->modifiers.first;
- int stack_index = -1;
- int a, ret = 1;
-
- if(sb->totpoint == 0) return 0;
+ PTCacheID pid;
+ PTCacheFile *pf;
+ int a;
+ if(sb->totpoint == 0)
+ return 0;
+
+ BKE_ptcache_id_from_softbody(&pid, ob, sb);
+ pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, framenr);
+ if(!pf)
+ return 0;
- if(sb->particles)
- stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,sb->particles));
- else {
- for(a=0; md; md=md->next, a++) {
- if(md->type == eModifierType_Softbody) {
- stack_index = a;
- break;
- }
+ for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) {
+ if(!BKE_ptcache_file_read_floats(pf, bp->pos, 3)) {
+ BKE_ptcache_file_close(pf);
+ return 0;
}
}
- fp = BKE_ptcache_id_fopen((ID *)ob, 'r', framenr, stack_index);
- if(!fp)
- ret = 0;
- else {
- for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++)
- if(fread(&bp->pos, sizeof(float), 3, fp) != 3) {
- ret = 0;
- break;
- }
- /*read velocities too !*/
- for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++){
- if(fread(&bp->vec, sizeof(float), 3, fp) != 3) {
- ret = 0;
- break;
- }
- }
- fclose(fp);
+ for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) {
+ if(!BKE_ptcache_file_read_floats(pf, bp->vec, 3)) {
+ BKE_ptcache_file_close(pf);
+ return 0;
+ }
}
- return ret;
+ BKE_ptcache_file_close(pf);
+
+ return 1;
}
+
/* +++ ************ maintaining scratch *************** */
void sb_new_scratch(SoftBody *sb)
{
@@ -3376,6 +3337,9 @@ SoftBody *sbNew(void)
/*todo backward file compat should set sb->shearstiff = 1.0f while reading old files*/
sb->shearstiff = 1.0f;
sb->solverflags |= SBSO_OLDERR;
+
+ sb->pointcache = BKE_ptcache_add();
+
return sb;
}
@@ -3383,14 +3347,19 @@ SoftBody *sbNew(void)
void sbFree(SoftBody *sb)
{
free_softbody_intern(sb);
+ BKE_ptcache_free(sb->pointcache);
MEM_freeN(sb);
}
+void sbFreeSimulation(SoftBody *sb)
+{
+ free_softbody_intern(sb);
+}
/* makes totally fresh start situation */
void sbObjectToSoftbody(Object *ob)
{
- ob->softflag |= OB_SB_REDO;
+ //ob->softflag |= OB_SB_REDO;
free_softbody_intern(ob->soft);
}
@@ -3414,323 +3383,406 @@ void sbSetInterruptCallBack(int (*f)(void))
SB_localInterruptCallBack = f;
}
-
-/* simulates one step. framenr is in frames */
-void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts)
+static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCos)[3], int numVerts)
{
- ParticleSystemModifierData *psmd=0;
- ParticleData *pa=0;
- SoftBody *sb;
+ ParticleSystemModifierData *psmd= NULL;
+ ParticleData *pa= NULL;
HairKey *key= NULL;
BodyPoint *bp;
+ float hairmat[4][4];
int a;
- float dtime,ctime,forcetime;
+
+ /* update the vertex locations */
+ if(sb->particles) {
+ psmd= psys_get_modifier(ob,sb->particles);
+ pa= sb->particles->particles;
+ key= pa->hair;
+
+ psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
+ }
+
+ for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
+ /* store where goals are now */
+ VECCOPY(bp->origS, bp->origE);
+ /* copy the position of the goals at desired end time */
+ if(sb->particles) {
+ if(key == pa->hair + pa->totkey) {
+ pa++;
+ key = pa->hair;
+
+ psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
+ }
+ VECCOPY(bp->origE, key->co);
+ Mat4MulVecfl(hairmat,bp->origE);
+
+ key++;
+ }
+ else{
+ VECCOPY(bp->origE, vertexCos[a]);
+ /* vertexCos came from local world, go global */
+ Mat4MulVecfl(ob->obmat, bp->origE);
+ }
+ /* just to be save give bp->origT a defined value
+ will be calulated in interpolate_exciter()*/
+ VECCOPY(bp->origT, bp->origE);
+ }
+}
+
+static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int numVerts)
+{
+ ParticleSystemModifierData *psmd= NULL;
+ HairKey *key= NULL;
+ ParticleData *pa= NULL;
+ BodyPoint *bp;
float hairmat[4][4];
+ int a;
- /* This part only sets goals and springs, based on original mesh/curve/lattice data.
- Copying coordinates happens in next chunk by setting softbody flag OB_SB_RESET */
- /* remake softbody if: */
- if( (ob->softflag & OB_SB_REDO) || /* signal after weightpainting */
- (ob->soft==NULL) || /* just to be nice we allow full init */
- (ob->soft->bpoint==NULL) || /* after reading new file, or acceptable as signal to refresh */
- (numVerts!=ob->soft->totpoint) || /* should never happen, just to be safe */
- ((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) /* happens when in UI edges was set */
- {
- if(ob->soft && ob->soft->bpoint) /* don't clear on file load */
- softbody_clear_cache(ob, framenr);
+ if(sb->particles) {
+ psmd= psys_get_modifier(ob, sb->particles);
+ pa= sb->particles->particles;
+ key= pa->hair;
- if(ob->soft->particles){
- particles_to_softbody(ob);
+ psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
+ }
+
+ for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
+ if(sb->particles) {
+ if(key == pa->hair + pa->totkey) {
+ pa++;
+ key = pa->hair;
+
+ psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
+ }
+ VECCOPY(bp->pos, key->co);
+ Mat4MulVecfl(hairmat, bp->pos);
+ key++;
+ }
+ else {
+ VECCOPY(bp->pos, vertexCos[a]);
+ Mat4MulVecfl(ob->obmat, bp->pos); /* yep, sofbody is global coords*/
}
- else switch(ob->type) {
+ VECCOPY(bp->origS, bp->pos);
+ VECCOPY(bp->origE, bp->pos);
+ VECCOPY(bp->origT, bp->pos);
+ bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0f;
+
+ /* the bp->prev*'s are for rolling back from a canceled try to propagate in time
+ adaptive step size algo in a nutshell:
+ 1. set sheduled time step to new dtime
+ 2. try to advance the sheduled time step, beeing optimistic execute it
+ 3. check for success
+ 3.a we 're fine continue, may be we can increase sheduled time again ?? if so, do so!
+ 3.b we did exceed error limit --> roll back, shorten the sheduled time and try again at 2.
+ 4. check if we did reach dtime
+ 4.a nope we need to do some more at 2.
+ 4.b yup we're done
+ */
+
+ VECCOPY(bp->prevpos, bp->pos);
+ VECCOPY(bp->prevvec, bp->vec);
+ VECCOPY(bp->prevdx, bp->vec);
+ VECCOPY(bp->prevdv, bp->vec);
+ }
+
+ /* make a nice clean scratch struc */
+ free_scratch(sb); /* clear if any */
+ sb_new_scratch(sb); /* make a new */
+ sb->scratch->needstobuildcollider=1;
+
+ if((sb->particles)==0) {
+ /* copy some info to scratch */
+ switch(ob->type) {
case OB_MESH:
- mesh_to_softbody(ob);
+ if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob);
break;
case OB_LATTICE:
- lattice_to_softbody(ob);
break;
case OB_CURVE:
case OB_SURF:
- curve_surf_to_softbody(ob);
break;
default:
- renew_softbody(ob, numVerts, 0);
break;
}
-
- /* still need to update to correct vertex locations, happens on next step */
- ob->softflag |= OB_SB_RESET;
- ob->softflag &= ~OB_SB_REDO;
}
+}
- sb= ob->soft;
+static void softbody_step(Object *ob, SoftBody *sb, float dtime)
+{
+ /* the simulator */
+ float forcetime;
+ double sct,sst=PIL_check_seconds_timer();
+ ccd_update_deflector_hache(ob,sb->scratch->colliderhash);
- /* still no points? go away */
- if(sb->totpoint==0) return;
+ if(sb->scratch->needstobuildcollider){
+ if (query_external_colliders(ob)){
+ ccd_build_deflector_hache(ob,sb->scratch->colliderhash);
+ }
+ sb->scratch->needstobuildcollider=0;
+ }
+
+ if (sb->solver_ID < 2) {
+ /* special case of 2nd order Runge-Kutta type AKA Heun */
+ int mid_flags=0;
+ float err = 0;
+ float forcetimemax = 1.0f;
+ float forcetimemin = 0.001f;
+ float timedone =0.0; /* how far did we get without violating error condition */
+ /* loops = counter for emergency brake
+ * we don't want to lock up the system if physics fail
+ */
+ int loops =0 ;
+ SoftHeunTol = sb->rklimit; /* humm .. this should be calculated from sb parameters and sizes */
+ if (sb->minloops > 0) forcetimemax = 1.0f / sb->minloops;
+
+ if (sb->maxloops > 0) forcetimemin = 1.0f / sb->maxloops;
+
+ if(sb->solver_ID>0) mid_flags |= MID_PRESERVE;
+
+ //forcetime = dtime; /* hope for integrating in one step */
+ forcetime =forcetimemax; /* hope for integrating in one step */
+ while ( (ABS(timedone) < ABS(dtime)) && (loops < 2000) )
+ {
+ /* set goals in time */
+ interpolate_exciter(ob,200,(int)(200.0*(timedone/dtime)));
+
+ sb->scratch->flag &= ~SBF_DOFUZZY;
+ /* do predictive euler step */
+ softbody_calc_forces(ob, forcetime,timedone/dtime,0);
+ softbody_apply_forces(ob, forcetime, 1, NULL,mid_flags);
- if(sb->particles){
- psmd=psys_get_modifier(ob,sb->particles);
- pa=sb->particles->particles;
- }
- /* checking time: */
+ /* crop new slope values to do averaged slope step */
+ softbody_calc_forces(ob, forcetime,timedone/dtime,0);
+ softbody_apply_forces(ob, forcetime, 2, &err,mid_flags);
- ctime= bsystem_time(ob, framenr, 0.0);
+ softbody_apply_goalsnap(ob);
+
+ if (err > SoftHeunTol) { /* error needs to be scaled to some quantity */
+
+ if (forcetime > forcetimemin){
+ forcetime = MAX2(forcetime / 2.0f,forcetimemin);
+ softbody_restore_prev_step(ob);
+ //printf("down,");
+ }
+ else {
+ timedone += forcetime;
+ }
+ }
+ else {
+ float newtime = forcetime * 1.1f; /* hope for 1.1 times better conditions in next step */
+
+ if (sb->scratch->flag & SBF_DOFUZZY){
+ //if (err > SoftHeunTol/(2.0f*sb->fuzzyness)) { /* stay with this stepsize unless err really small */
+ newtime = forcetime;
+ //}
+ }
+ else {
+ if (err > SoftHeunTol/2.0f) { /* stay with this stepsize unless err really small */
+ newtime = forcetime;
+ }
+ }
+ timedone += forcetime;
+ newtime=MIN2(forcetimemax,MAX2(newtime,forcetimemin));
+ //if (newtime > forcetime) printf("up,");
+ if (forcetime > 0.0)
+ forcetime = MIN2(dtime - timedone,newtime);
+ else
+ forcetime = MAX2(dtime - timedone,newtime);
+ }
+ loops++;
+ if(sb->solverflags & SBSO_MONITOR ){
+ sct=PIL_check_seconds_timer();
+ if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone);
+ }
+ /* ask for user break */
+ if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
- if (ob->softflag&OB_SB_RESET) {
- dtime = 0.0;
- } else {
- dtime= ctime - sb->ctime;
+ }
+ /* move snapped to final position */
+ interpolate_exciter(ob, 2, 2);
+ softbody_apply_goalsnap(ob);
+
+ // if(G.f & G_DEBUG){
+ if(sb->solverflags & SBSO_MONITOR ){
+ if (loops > HEUNWARNLIMIT) /* monitor high loop counts */
+ printf("\r needed %d steps/frame ",loops);
+ }
+
}
+ else if (sb->solver_ID == 2)
+ {/* do semi "fake" implicit euler */
+ //removed
+ }/*SOLVER SELECT*/
+ else if (sb->solver_ID == 4)
+ {
+ /* do semi "fake" implicit euler */
+ }/*SOLVER SELECT*/
+ else if (sb->solver_ID == 3){
+ /* do "stupid" semi "fake" implicit euler */
+ //removed
- if(softbody_read_cache(ob, framenr)) {
- if(sb->particles==0)
- softbody_to_object(ob, vertexCos, numVerts, sb->local);
- sb->ctime = ctime;
- return;
+ }/*SOLVER SELECT*/
+ else{
+ printf("softbody no valid solver ID!");
+ }/*SOLVER SELECT*/
+ if(sb->plastic){ apply_spring_memory(ob);}
+
+ if(sb->solverflags & SBSO_MONITOR ){
+ sct=PIL_check_seconds_timer();
+ if (sct-sst > 0.5f) printf(" solver time %f %s \r",sct-sst,ob->id.name);
}
+}
- /* the simulator */
+/* simulates one step. framenr is in frames */
+void sbObjectStep(Object *ob, float cfra, float (*vertexCos)[3], int numVerts)
+{
+ ParticleSystemModifierData *psmd=0;
+ ParticleData *pa=0;
+ SoftBody *sb= ob->soft;
+ PointCache *cache;
+ PTCacheID pid;
+ float dtime, timescale;
+ int framedelta, framenr, startframe, endframe;
- /* update the vertex locations */
- if (dtime!=0.0) {
- if(sb->particles) {
- pa=sb->particles->particles;
- key = pa->hair;
+ cache= sb->pointcache;
- psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
- }
+ framenr= (int)cfra;
+ framedelta= framenr - cache->simframe;
- for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
- /* store where goals are now */
- VECCOPY(bp->origS, bp->origE);
- /* copy the position of the goals at desired end time */
- if(sb->particles) {
- if(key == pa->hair + pa->totkey) {
- pa++;
- key = pa->hair;
+ BKE_ptcache_id_from_softbody(&pid, ob, sb);
+ BKE_ptcache_id_time(&pid, framenr, &startframe, &endframe, &timescale);
- psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
- }
- VECCOPY(bp->origE, key->co);
- Mat4MulVecfl(hairmat,bp->origE);
+ /* check for changes in mesh, should only happen in case the mesh
+ * structure changes during an animation */
+ if(sb->bpoint && numVerts != sb->totpoint) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
- key++;
- }
- else{
- VECCOPY(bp->origE, vertexCos[a]);
- /* vertexCos came from local world, go global */
- Mat4MulVecfl(ob->obmat, bp->origE);
- }
- /* just to be save give bp->origT a defined value
- will be calulated in interpolate_exciter()*/
- VECCOPY(bp->origT, bp->origE);
- }
+ return;
}
- if((ob->softflag&OB_SB_RESET) || /* got a reset signal */
- (dtime<0.0) || /* back in time */
- (dtime>=9.9*G.scene->r.framelen) /* too far forward in time --> goals won't be accurate enough */
- )
- {
- if(sb->particles) {
- pa=sb->particles->particles;
- key = pa->hair;
-
- psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
- }
+ /* clamp frame ranges */
+ if(framenr < startframe) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
- for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
- if(sb->particles) {
- if(key == pa->hair + pa->totkey) {
- pa++;
- key = pa->hair;
+ return;
+ }
+ else if(framenr > endframe) {
+ framenr = endframe;
+ }
- psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
- }
- VECCOPY(bp->pos, key->co);
- Mat4MulVecfl(hairmat, bp->pos);
- key++;
- }
- else {
- VECCOPY(bp->pos, vertexCos[a]);
- Mat4MulVecfl(ob->obmat, bp->pos); /* yep, sofbody is global coords*/
- }
- VECCOPY(bp->origS, bp->pos);
- VECCOPY(bp->origE, bp->pos);
- VECCOPY(bp->origT, bp->pos);
- bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0f;
-
- /* the bp->prev*'s are for rolling back from a canceled try to propagate in time
- adaptive step size algo in a nutshell:
- 1. set sheduled time step to new dtime
- 2. try to advance the sheduled time step, beeing optimistic execute it
- 3. check for success
- 3.a we 're fine continue, may be we can increase sheduled time again ?? if so, do so!
- 3.b we did exceed error limit --> roll back, shorten the sheduled time and try again at 2.
- 4. check if we did reach dtime
- 4.a nope we need to do some more at 2.
- 4.b yup we're done
- */
+ /* verify if we need to create the softbody data */
+ if(sb->bpoint == NULL ||
+ ((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) {
- VECCOPY(bp->prevpos, bp->pos);
- VECCOPY(bp->prevvec, bp->vec);
- VECCOPY(bp->prevdx, bp->vec);
- VECCOPY(bp->prevdv, bp->vec);
+ if(sb->particles){
+ particles_to_softbody(ob);
}
- /* make a nice clean scratch struc */
- free_scratch(sb); /* clear if any */
- sb_new_scratch(sb); /* make a new */
- sb->scratch->needstobuildcollider=1;
-
- if((sb->particles)==0) {
- /* copy some info to scratch */
+ else {
switch(ob->type) {
- case OB_MESH:
- if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob);
- break;
- case OB_LATTICE:
- break;
- case OB_CURVE:
- case OB_SURF:
- break;
- default:
- break;
+ case OB_MESH:
+ mesh_to_softbody(ob);
+ break;
+ case OB_LATTICE:
+ lattice_to_softbody(ob);
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ curve_surf_to_softbody(ob);
+ break;
+ default:
+ renew_softbody(ob, numVerts, 0);
+ break;
}
}
- ob->softflag &= ~OB_SB_RESET;
+ softbody_update_positions(ob, sb, vertexCos, numVerts);
+ softbody_reset(ob, sb, vertexCos, numVerts);
}
- else if(dtime>0.0) {
- double sct,sst=PIL_check_seconds_timer();
- ccd_update_deflector_hache(ob,sb->scratch->colliderhash);
+ /* continue physics special case */
+ if(BKE_ptcache_get_continue_physics()) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
- if(sb->scratch->needstobuildcollider){
- if (query_external_colliders(ob)){
- ccd_build_deflector_hache(ob,sb->scratch->colliderhash);
- }
- sb->scratch->needstobuildcollider=0;
- }
+ /* do simulation */
+ dtime = timescale;
+ softbody_update_positions(ob, sb, vertexCos, numVerts);
+ softbody_step(ob, sb, dtime);
- if (sb->solver_ID < 2) {
- /* special case of 2nd order Runge-Kutta type AKA Heun */
- int mid_flags=0;
- float err = 0;
- float forcetimemax = 1.0f;
- float forcetimemin = 0.001f;
- float timedone =0.0; /* how far did we get without violating error condition */
- /* loops = counter for emergency brake
- * we don't want to lock up the system if physics fail
- */
- int loops =0 ;
- SoftHeunTol = sb->rklimit; /* humm .. this should be calculated from sb parameters and sizes */
- if (sb->minloops > 0) forcetimemax = 1.0f / sb->minloops;
-
- if (sb->maxloops > 0) forcetimemin = 1.0f / sb->maxloops;
+ if(sb->particles==0)
+ softbody_to_object(ob, vertexCos, numVerts, 0);
- if(sb->solver_ID>0) mid_flags |= MID_PRESERVE;
-
- //forcetime = dtime; /* hope for integrating in one step */
- forcetime =forcetimemax; /* hope for integrating in one step */
- while ( (ABS(timedone) < ABS(dtime)) && (loops < 2000) )
- {
- /* set goals in time */
- interpolate_exciter(ob,200,(int)(200.0*(timedone/dtime)));
-
- sb->scratch->flag &= ~SBF_DOFUZZY;
- /* do predictive euler step */
- softbody_calc_forces(ob, forcetime,timedone/dtime,0);
- softbody_apply_forces(ob, forcetime, 1, NULL,mid_flags);
+ return;
+ }
+ /* still no points? go away */
+ if(sb->totpoint==0) return;
- /* crop new slope values to do averaged slope step */
- softbody_calc_forces(ob, forcetime,timedone/dtime,0);
- softbody_apply_forces(ob, forcetime, 2, &err,mid_flags);
+ if(sb->particles){
+ psmd= psys_get_modifier(ob, sb->particles);
+ pa= sb->particles->particles;
+ }
- softbody_apply_goalsnap(ob);
-
- if (err > SoftHeunTol) { /* error needs to be scaled to some quantity */
-
- if (forcetime > forcetimemin){
- forcetime = MAX2(forcetime / 2.0f,forcetimemin);
- softbody_restore_prev_step(ob);
- //printf("down,");
- }
- else {
- timedone += forcetime;
- }
- }
- else {
- float newtime = forcetime * 1.1f; /* hope for 1.1 times better conditions in next step */
-
- if (sb->scratch->flag & SBF_DOFUZZY){
- //if (err > SoftHeunTol/(2.0f*sb->fuzzyness)) { /* stay with this stepsize unless err really small */
- newtime = forcetime;
- //}
- }
- else {
- if (err > SoftHeunTol/2.0f) { /* stay with this stepsize unless err really small */
- newtime = forcetime;
- }
- }
- timedone += forcetime;
- newtime=MIN2(forcetimemax,MAX2(newtime,forcetimemin));
- //if (newtime > forcetime) printf("up,");
- if (forcetime > 0.0)
- forcetime = MIN2(dtime - timedone,newtime);
- else
- forcetime = MAX2(dtime - timedone,newtime);
- }
- loops++;
- if(sb->solverflags & SBSO_MONITOR ){
- sct=PIL_check_seconds_timer();
- if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone);
- }
- /* ask for user break */
- if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
+ /* try to read from cache */
+ if(softbody_read_cache(ob, framenr)) {
+ if(sb->particles==0)
+ softbody_to_object(ob, vertexCos, numVerts, sb->local);
- }
- /* move snapped to final position */
- interpolate_exciter(ob, 2, 2);
- softbody_apply_goalsnap(ob);
-
- // if(G.f & G_DEBUG){
- if(sb->solverflags & SBSO_MONITOR ){
- if (loops > HEUNWARNLIMIT) /* monitor high loop counts */
- printf("\r needed %d steps/frame ",loops);
- }
-
- }
- else if (sb->solver_ID == 2)
- {/* do semi "fake" implicit euler */
- //removed
- }/*SOLVER SELECT*/
- else if (sb->solver_ID == 4)
- {
- /* do semi "fake" implicit euler */
- }/*SOLVER SELECT*/
- else if (sb->solver_ID == 3){
- /* do "stupid" semi "fake" implicit euler */
- //removed
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
- }/*SOLVER SELECT*/
- else{
- printf("softbody no valid solver ID!");
- }/*SOLVER SELECT*/
- if(sb->plastic){ apply_spring_memory(ob);}
+ return;
+ }
+ else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
+ /* if baked and nothing in cache, do nothing */
+ if(cache->flag & PTCACHE_SIMULATION_VALID) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ }
- if(sb->solverflags & SBSO_MONITOR ){
- sct=PIL_check_seconds_timer();
- if (sct-sst > 0.5f) printf(" solver time %f %s \r",sct-sst,ob->id.name);
- }
+ return;
}
- if(sb->particles==0)
- softbody_to_object(ob, vertexCos, numVerts, 0);
- sb->ctime= ctime;
+ if(framenr == startframe) {
+ /* first frame, no simulation to do, just set the positions */
+ softbody_update_positions(ob, sb, vertexCos, numVerts);
+
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
+
+ /* don't write cache on first frame, but on second frame write
+ * cache for frame 1 and 2 */
+ }
+ else if(framedelta == 1) {
+ /* if on second frame, write cache for first frame */
+ if(framenr == startframe+1)
+ sbWriteCache(ob, startframe);
+
+ softbody_update_positions(ob, sb, vertexCos, numVerts);
+
+ /* do simulation */
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
+
+ /* checking time: */
+ dtime = framedelta*timescale;
- softbody_write_cache(ob, framenr);
+ softbody_step(ob, sb, dtime);
+
+ if(sb->particles==0)
+ softbody_to_object(ob, vertexCos, numVerts, 0);
+
+ sbWriteCache(ob, framenr);
+ }
+ else {
+ /* time step backwards or too large forward - do nothing */
+ if(cache->flag & PTCACHE_SIMULATION_VALID) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ }
+ }
}
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index e5b11412aa1..a9da0c9c738 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -333,7 +333,7 @@ int BLI_delete(char *file, int dir, int recursive)
else {
if (recursive) sprintf(str, "/bin/rm -rf \"%s\"", file);
else if (dir) sprintf(str, "/bin/rmdir \"%s\"", file);
- else sprintf(str, "/bin/rm -f \"%s\"", file);
+ else remove(file); //sprintf(str, "/bin/rm -f \"%s\"", file);
return system(str);
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index b055e62cddb..7fe023c782d 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -134,6 +134,7 @@
#include "BKE_node.h" // for tree type defines
#include "BKE_object.h"
#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_property.h" // for get_property
#include "BKE_sca.h" // for init_actuator
#include "BKE_scene.h"
@@ -2529,6 +2530,12 @@ static void direct_link_material(FileData *fd, Material *ma)
/* ************ READ PARTICLE SETTINGS ***************** */
+static void direct_link_pointcache(FileData *fd, PointCache *cache)
+{
+ cache->flag &= ~(PTCACHE_SIMULATION_VALID|PTCACHE_BAKE_EDIT_ACTIVE);
+ cache->simframe= 0;
+}
+
static void lib_link_particlesettings(FileData *fd, Main *main)
{
ParticleSettings *part;
@@ -2582,8 +2589,12 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
}
if(psys->particles && psys->particles->keys){
ParticleData *pa = psys->particles;
- for(a=0; a<psys->totpart; a++, pa++)
- pa->keys=newdataadr(fd,pa->keys);
+ for(a=0; a<psys->totpart; a++, pa++) {
+ pa->keys= NULL;
+ pa->totkey= 0;
+ }
+
+ psys->flag &= ~PSYS_KEYED;
}
psys->child=newdataadr(fd,psys->child);
psys->effectors.first=psys->effectors.last=0;
@@ -2595,12 +2606,20 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
sb->bpoint= NULL; // init pointers so it gets rebuilt nicely
sb->bspring= NULL;
sb->scratch= NULL;
+
+ sb->pointcache= newdataadr(fd, sb->pointcache);
+ if(sb->pointcache)
+ direct_link_pointcache(fd, sb->pointcache);
}
psys->edit = 0;
psys->pathcache = 0;
psys->childcache = 0;
psys->reactevents.first = psys->reactevents.last = 0;
+
+ psys->pointcache= newdataadr(fd, psys->pointcache);
+ if(psys->pointcache)
+ direct_link_pointcache(fd, psys->pointcache);
}
return;
}
@@ -3009,8 +3028,8 @@ static void lib_link_object(FileData *fd, Main *main)
}
-static void direct_link_pose(FileData *fd, bPose *pose) {
-
+static void direct_link_pose(FileData *fd, bPose *pose)
+{
bPoseChannel *pchan;
if (!pose)
@@ -3054,12 +3073,12 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
+ clmd->point_cache= newdataadr(fd, clmd->point_cache);
+
+ if(clmd->point_cache)
+ direct_link_pointcache(fd, clmd->point_cache);
- if(clmd->sim_parms)
- {
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_LOADED;
- clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
-
+ if(clmd->sim_parms) {
if(clmd->sim_parms->presets > 10)
clmd->sim_parms->presets = 0;
}
@@ -3245,6 +3264,10 @@ static void direct_link_object(FileData *fd, Object *ob)
sb->keys[a]= newdataadr(fd, sb->keys[a]);
}
}
+
+ sb->pointcache= newdataadr(fd, sb->pointcache);
+ if(sb->pointcache)
+ direct_link_pointcache(fd, sb->pointcache);
}
ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
if(ob->fluidsimSettings) {
@@ -6910,6 +6933,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
Mesh *me;
bNodeTree *ntree;
Tex *tex;
+ ModifierData *md;
+ ParticleSystem *psys;
/* unless the file was created 2.44.3 but not 2.45, update the constraints */
if ( !(main->versionfile==244 && main->subversionfile==3) &&
@@ -7034,6 +7059,27 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ /* add point caches */
+ for(ob=main->object.first; ob; ob=ob->id.next) {
+ if(ob->soft && !ob->soft->pointcache)
+ ob->soft->pointcache= BKE_ptcache_add();
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ if(psys->soft && !psys->soft->pointcache)
+ psys->soft->pointcache= BKE_ptcache_add();
+ if(!psys->pointcache)
+ psys->pointcache= BKE_ptcache_add();
+ }
+
+ for(md=ob->modifiers.first; md; md=md->next) {
+ if(md->type==eModifierType_Cloth) {
+ ClothModifierData *clmd = (ClothModifierData*) md;
+ if(!clmd->point_cache)
+ clmd->point_cache= BKE_ptcache_add();
+ }
+ }
+ }
+
/* Copy over old per-level multires vertex data
into a single vertex array in struct Multires */
for(me = main->mesh.first; me; me=me->id.next) {
@@ -7287,7 +7333,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
sb->keys = NULL;
sb->totkey = 0;
- ob->softflag &= ~OB_SB_BAKESET;
}
}
}
@@ -7311,7 +7356,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
sb->keys = NULL;
sb->totkey = 0;
- ob->softflag &= ~OB_SB_BAKESET;
}
/* convert old particles to new system */
@@ -7333,7 +7377,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
part->id.flag |= (ob->id.flag & LIB_NEEDLINK);
psys->totpart=0;
- psys->flag=PSYS_ENABLED|PSYS_CURRENT;
+ psys->flag= PSYS_ENABLED|PSYS_CURRENT;
BLI_addtail(&ob->particlesystem, psys);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 6308f092044..269ea1e8e02 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -576,16 +576,11 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
for(a=0; a<psys->totpart; a++, pa++)
writestruct(wd, DATA, "HairKey", pa->totkey, pa->hair);
}
-
- if(psys->particles->keys) {
- ParticleData *pa = psys->particles;
-
- for(a=0; a<psys->totpart; a++, pa++)
- writestruct(wd, DATA, "ParticleKey", pa->totkey, pa->keys);
- }
}
if(psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child);
writestruct(wd, DATA, "SoftBody", 1, psys->soft);
+ if(psys->soft) writestruct(wd, DATA, "PointCache", 1, psys->soft->pointcache);
+ writestruct(wd, DATA, "PointCache", 1, psys->pointcache);
}
}
@@ -864,7 +859,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms);
writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms);
-
+ writestruct(wd, DATA, "PointCache", 1, clmd->point_cache);
}
else if (md->type==eModifierType_Collision) {
@@ -930,6 +925,7 @@ static void write_objects(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
writestruct(wd, DATA, "SoftBody", 1, ob->soft);
+ if(ob->soft) writestruct(wd, DATA, "PointCache", 1, ob->soft->pointcache);
writestruct(wd, DATA, "FluidsimSettings", 1, ob->fluidsimSettings); // NT
write_particlesystems(wd, &ob->particlesystem);
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index b3e0e1a23e0..17a887e9cf4 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -295,13 +295,10 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_GROUP_RELINK 1460
#define B_OBJECT_IPOFLAG 1461
-#define B_BAKEABLE_CHANGE 1470
+#define B_BAKE_CACHE_CHANGE 1470
/* Cloth sim button defines */
-#define B_CLOTH_CLEARCACHEALL 1480
-#define B_CLOTH_CLEARCACHEFRAME 1481
-#define B_CLOTH_CHANGEPREROLL 1482
-#define B_CLOTH_RENEW 1483
+#define B_CLOTH_CHANGEPREROLL 1480
/* *********************** */
#define B_WORLDBUTS 1600
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index b8a6ddddfa7..5f6aff096f2 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -32,7 +32,6 @@
#ifndef DNA_CLOTH_TYPES_H
#define DNA_CLOTH_TYPES_H
-
/**
* This struct contains all the global data required to run a simulation.
* At the time of this writing, this structure contains data appropriate
@@ -61,8 +60,8 @@ typedef struct ClothSimSettings
float structural; /* Structural spring stiffness. */
float shear; /* Shear spring stiffness. */
float bending; /* Flexion spring stiffness. */
- float sim_time;
- int flags; /* flags, see CSIMSETT_FLAGS enum above. */
+ float padf;
+ int flags; /* flags, see CSIMSETT_FLAGS enum above. */
short solver_type; /* which solver should be used? txold */
short vgroup_bend; /* vertex group for scaling bending stiffness */
float maxgoal; /* see SB */
@@ -74,21 +73,14 @@ typedef struct ClothSimSettings
int goalfrict;
float goalspring;
int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */
- int lastframe; /* frame on which simulation stops */
- int firstframe; /* frame on which simulation starts */
- int lastcachedframe;
- int editedframe; /* which frame is in buffer */
- int autoprotect; /* starting from this frame, cache gets protected */
float max_bend; /* max bending scaling value, min is "bending" */
float max_struct; /* max structural scaling value, min is "structural" */
float max_shear; /* max shear scaling value, UNUSED */
- int firstcachedframe;
float avg_spring_len; /* used for normalized springs */
short presets; /* used for presets on GUI */
short pad;
float timescale; /* parameter how fast cloth runs */
-}
-ClothSimSettings;
+} ClothSimSettings;
typedef struct ClothCollSettings
@@ -101,9 +93,7 @@ typedef struct ClothCollSettings
struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */
int flags; /* collision flags defined in BKE_cloth.h */
float selfepsilon; /* for selfcollision */
-}
-ClothCollSettings;
-
+} ClothCollSettings;
/**
* This structure describes a cloth object against which the
@@ -130,7 +120,6 @@ typedef struct Cloth
struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
struct Implicit_Data *implicitEM; /* our implicit solver connects to this pointer */
struct EdgeHash *edgehash; /* used for selfcollisions */
-}
-Cloth;
+} Cloth;
#endif
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index c62d012643a..b7b43817474 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -371,6 +371,7 @@ typedef struct ClothModifierData {
struct Cloth *clothObject; /* The internal data structure for cloth. */
struct ClothSimSettings *sim_parms; /* definition is in DNA_cloth_types.h */
struct ClothCollSettings *coll_parms; /* definition is in DNA_cloth_types.h */
+ struct PointCache *point_cache; /* definition is in DNA_object_force.h */
} ClothModifierData;
typedef struct CollisionModifierData {
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index 70e0e91eca6..192c74283f9 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -72,6 +72,13 @@ typedef struct PartDeflect {
struct Tex *tex; /* Texture of the texture effector */
} PartDeflect;
+typedef struct PointCache {
+ int flag; /* generic flag */
+ int simframe; /* current frame of simulation (only if SIMULATION_VALID) */
+ int startframe; /* simulation start frame */
+ int endframe; /* simulation end frame */
+ int editframe; /* frame being edited (runtime only) */
+} PointCache;
typedef struct SBVertex {
float vec[4];
@@ -84,7 +91,7 @@ typedef struct SoftBody {
int totpoint, totspring;
struct BodyPoint *bpoint; /* not saved in file */
struct BodySpring *bspring; /* not saved in file */
- float ctime; /* last time calculated */
+ float pad;
/* part of UI: */
@@ -137,6 +144,8 @@ typedef struct SoftBody {
float shearstiff;
float inpush;
+ struct PointCache *pointcache;
+
} SoftBody;
/* pd->forcefield: Effector Fields types */
@@ -177,21 +186,29 @@ typedef struct SoftBody {
#define PFIELD_TEX_GRAD 1
#define PFIELD_TEX_CURL 2
+/* pointcache->flag */
+#define PTCACHE_BAKED 1
+#define PTCACHE_OUTDATED 2
+#define PTCACHE_SIMULATION_VALID 4
+#define PTCACHE_BAKING 8
+#define PTCACHE_BAKE_EDIT 16
+#define PTCACHE_BAKE_EDIT_ACTIVE 32
+
/* ob->softflag */
#define OB_SB_ENABLE 1
#define OB_SB_GOAL 2
#define OB_SB_EDGES 4
#define OB_SB_QUADS 8
#define OB_SB_POSTDEF 16
-#define OB_SB_REDO 32
-#define OB_SB_BAKESET 64
-#define OB_SB_BAKEDO 128
-#define OB_SB_RESET 256
+// #define OB_SB_REDO 32
+// #define OB_SB_BAKESET 64
+// #define OB_SB_BAKEDO 128
+// #define OB_SB_RESET 256
#define OB_SB_SELF 512
#define OB_SB_FACECOLL 1024
#define OB_SB_EDGECOLL 2048
#define OB_SB_COLLFINAL 4096
-#define OB_SB_PROTECT_CACHE 8192
+//#define OB_SB_PROTECT_CACHE 8192
#define OB_SB_AERO_ANGLE 16384
/* sb->solverflags */
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 2203de1c862..d2f27665862 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -206,6 +206,9 @@ typedef struct ParticleSystem{
/* temporary storage during render */
void *renderdata;
+
+ /* point cache */
+ struct PointCache *pointcache;
}ParticleSystem;
/* general particle maximums */
@@ -387,7 +390,7 @@ typedef struct ParticleSystem{
//#define PSYS_BAKING 2
//#define PSYS_BAKE_UI 4
#define PSYS_KEYED_TIME 8
-#define PSYS_ENABLED 16
+#define PSYS_ENABLED 16 /* deprecated */
#define PSYS_FIRST_KEYED 32
#define PSYS_DRAWING 64
//#define PSYS_SOFT_BAKE 128
@@ -395,7 +398,8 @@ typedef struct ParticleSystem{
#define PSYS_HAIR_DONE 512
#define PSYS_KEYED 1024
#define PSYS_EDITED 2048
-#define PSYS_PROTECT_CACHE 4096
+//#define PSYS_PROTECT_CACHE 4096
+#define PSYS_DISABLED 8192
/* pars->flag */
#define PARS_UNEXIST 1
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index f96a4fea891..9e49b3a5e0c 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -633,6 +633,7 @@ typedef struct SpaceImaSel {
#define TIME_WITH_SEQ_AUDIO 16
#define TIME_SEQ 32
#define TIME_ALL_IMAGE_WIN 64
+#define TIME_CONTINUE_PHYSICS 128
/* sseq->mainb */
#define SEQ_DRAW_SEQUENCE 0
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 144b266759d..80ca4db9cac 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -930,7 +930,6 @@ void do_modifier_panels(unsigned short event)
break;
case B_MODIFIER_RECALC:
- ob->softflag |= OB_SB_RESET;
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWIMAGE, 0);
@@ -2230,11 +2229,11 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiButSetFunc(but, modifiers_reassignHook, ob, md);
}
} else if (md->type==eModifierType_Softbody) {
- uiDefBut(block, LABEL, 1, "See Softbody panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 1, "See Soft Body panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
} else if (md->type==eModifierType_Cloth) {
uiDefBut(block, LABEL, 1, "See Cloth panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
} else if (md->type==eModifierType_Collision) {
- uiDefBut(block, LABEL, 1, "See Deflection panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 1, "See Collision panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
} else if (md->type==eModifierType_Boolean) {
BooleanModifierData *bmd = (BooleanModifierData*) md;
uiDefButI(block, MENU, B_MODIFIER_RECALC, "Operation%t|Intersect%x0|Union%x1|Difference%x2", lx,(cy-=19),buttonWidth,19, &bmd->operation, 0.0, 1.0, 0, 0, "Boolean operation to perform");
@@ -2444,17 +2443,17 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
}
if (md->error) {
- char str[512];
-
- y -= 20;
+ y -= 6;
uiBlockSetCol(block, color);
/* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
uiDefBut(block, ROUNDBOX, 0, "", x-10, y, width, 20, NULL, 5.0, 0.0, 15, 40, "");
uiBlockSetCol(block, TH_AUTO);
- sprintf(str, "Modifier Error: %s", md->error);
- uiDefBut(block, LABEL, B_NOP, str, x+15, y+15, width-35, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefIconBut(block,LABEL,B_NOP,ICON_ERROR, x-9, y,19,19, 0,0,0,0,0, "");
+ uiDefBut(block, LABEL, B_NOP, md->error, x+5, y, width-15, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ y -= 18;
}
uiClearButLock();
@@ -2481,7 +2480,7 @@ static void editing_panel_modifiers(Object *ob)
uiDefBlockBut(block, modifiers_add_menu, ob, "Add Modifier", 0, 190, 130, 20, "Add a new modifier");
sprintf(str, "To: %s", ob->id.name+2);
- uiDefBut(block, LABEL, 1, str, 140, 190, 150, 20, NULL, 0.0, 0.0, 0, 0, "Object whose modifier stack is being edited");
+ uiDefBut(block, LABEL, 1, str, 140, 190, 160, 20, NULL, 0.0, 0.0, 0, 0, "Object whose modifier stack is being edited");
xco = 0;
yco = 160;
@@ -3708,11 +3707,6 @@ void do_latticebuts(unsigned short event)
lt = ob->data;
if(ob==G.obedit) resizelattice(editLatt, lt->opntsu, lt->opntsv, lt->opntsw, NULL);
else resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, NULL);
- ob->softflag |= OB_SB_REDO;
- if(modifiers_isClothEnabled(ob)) {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- }
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
}
@@ -3720,11 +3714,6 @@ void do_latticebuts(unsigned short event)
if(ob) {
lt = ob->data;
resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, ob);
- ob->softflag |= OB_SB_REDO;
- if(modifiers_isClothEnabled(ob)) {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- }
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
}
@@ -5032,7 +5021,7 @@ static void editing_panel_mesh_tools1(Object *ob, Mesh *me)
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_tools1", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Mesh Tools 1", "Editing", 960, 0, 318, 204)==0) return;
+ if(uiNewPanel(curarea, block, "Mesh Tools More", "Editing", 960, 0, 318, 204)==0) return;
uiBlockBeginAlign(block);
uiDefBut(block, BUT,B_SELSWAP, "Select Swap", 955, 200, 106, 19, 0, 0, 0, 0, 0, "Selects unselected faces, and deselects selected faces (Ctrl+I)");
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index c88f280f847..aeb94ff769c 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -54,6 +54,7 @@
#include "BKE_softbody.h"
#include "BKE_utildefines.h"
#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -2052,72 +2053,133 @@ void do_constraintbuts(unsigned short event)
allqueue (REDRAWBUTSOBJECT, 0);
}
-void softbody_bake(Object *ob)
+void pointcache_bake(PTCacheID *pid, int startframe)
{
Base *base;
- SoftBody *sb;
ScrArea *sa;
+ PointCache *cache;
+ ListBase pidlist;
float frameleno= G.scene->r.framelen;
- int cfrao= CFRA, sfra=100000, efra=0, didbreak =0;
-
+ int cfrao= CFRA, didbreak =0, endframe, cstart, cend;
G.scene->r.framelen= 1.0; // baking has to be in uncorrected time
sbSetInterruptCallBack(blender_test_break); // make softbody module ESC aware
G.afbreek=0; // init global break system
- if(ob) {
- sb= ob->soft;
- sfra= MIN2(sfra, sb->sfra);
- efra= MAX2(efra, sb->efra);
- sbObjectToSoftbody(ob); // put softbody in restposition, free bake
- ob->softflag |= OB_SB_BAKEDO;
+ if(pid) {
+ cache= pid->cache;
+
+ BKE_ptcache_id_time(pid, 0.0f, &cstart, &cend, NULL);
+
+ startframe= startframe;
+ endframe= cend;
+
+ cache->flag |= PTCACHE_BAKING;
+ cache->flag &= ~PTCACHE_BAKED;
}
else {
+ startframe= MAXFRAME;
+ endframe= 0;
+
for(base=G.scene->base.first; base; base= base->next) {
if(TESTBASELIB(base)) {
- if(base->object->soft) {
- sb= base->object->soft;
- sfra= MIN2(sfra, sb->sfra);
- efra= MAX2(efra, sb->efra);
- sbObjectToSoftbody(base->object); // put softbody in restposition, free bake
- base->object->softflag |= OB_SB_BAKEDO;
+ BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+ for(pid=pidlist.first; pid; pid=pid->next) {
+ cache= pid->cache;
+
+ BKE_ptcache_id_time(pid, 0.0f, &cstart, &cend, NULL);
+
+ startframe= MIN2(startframe, cstart);
+ endframe= MAX2(endframe, cend);
+
+ cache->flag |= PTCACHE_BAKING;
+ cache->flag &= ~PTCACHE_BAKED;
}
+
+ BLI_freelistN(&pidlist);
}
}
}
- CFRA= sfra;
+ CFRA= startframe;
update_for_newframe_muted(); // put everything on this frame
curarea->win_swap= 0; // clean swapbuffers
- for(; CFRA <= efra; CFRA++) {
+ for(; CFRA <= endframe; CFRA++) {
set_timecursor(CFRA);
update_for_newframe_muted();
- for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
- if(sa->spacetype == SPACE_VIEW3D) {
+ for(sa= G.curscreen->areabase.first; sa; sa= sa->next)
+ if(sa->spacetype == SPACE_VIEW3D)
scrarea_do_windraw(sa);
- }
- }
screen_swapbuffers();
+
//blender_test_break() has a granularity of 10 ms, who cares .. baking the unit cube is kinda boring
- if (blender_test_break()){
+ if(blender_test_break()) {
didbreak = 1;
break;
}
+ }
+
+ if(didbreak && G.qual!=LR_SHIFTKEY) {
+ /* failed to bake, free the frames we baked */
+ if(pid) {
+ cache= pid->cache;
+
+ BKE_ptcache_id_time(pid, 0.0f, &cstart, &cend, NULL);
+
+ cache->flag &= ~PTCACHE_BAKING;
+ if(startframe == cstart)
+ cache->flag &= ~PTCACHE_BAKED;
+
+ BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, startframe-1);
+ }
+ else {
+ for(base=G.scene->base.first; base; base= base->next) {
+ if(TESTBASELIB(base)) {
+ BKE_ptcache_ids_from_object(&pidlist, base->object);
+ for(pid=pidlist.first; pid; pid=pid->next) {
+ cache= pid->cache;
+
+ BKE_ptcache_id_time(pid, 0.0f, &cstart, &cend, NULL);
+
+ cache->flag &= ~PTCACHE_BAKING;
+ if(startframe == cstart)
+ cache->flag &= ~PTCACHE_BAKED;
+
+ BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, startframe-1);
+ }
+
+ BLI_freelistN(&pidlist);
+ }
+ }
+ }
}
- if((didbreak)&&(G.qual!=LR_SHIFTKEY)) {
- if(ob)
- sbObjectToSoftbody(ob); // free bake
+ else {
+ /* succesfully finished baking */
+ if(pid) {
+ cache= pid->cache;
+
+ cache->flag &= ~PTCACHE_BAKING;
+ cache->flag |= PTCACHE_BAKED;
+ }
else {
for(base=G.scene->base.first; base; base= base->next) {
if(TESTBASELIB(base)) {
- if(base->object->soft) {
- sbObjectToSoftbody(base->object); // free bake
+ BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+ for(pid=pidlist.first; pid; pid=pid->next) {
+ cache= pid->cache;
+
+ cache->flag &= ~PTCACHE_BAKING;
+ cache->flag |= PTCACHE_BAKED;
}
+
+ BLI_freelistN(&pidlist);
}
}
}
@@ -2127,16 +2189,7 @@ void softbody_bake(Object *ob)
waitcursor(0);
sbSetInterruptCallBack(NULL); // softbody module won't ESC
G.afbreek=0; // reset global break system
-
- if(ob)
- ob->softflag &= ~OB_SB_BAKEDO;
- else {
- for(base=G.scene->base.first; base; base= base->next)
- if(TESTBASELIB(base))
- if(base->object->soft)
- base->object->softflag &= ~OB_SB_BAKEDO;
- }
-
+
CFRA= cfrao;
G.scene->r.framelen= frameleno;
update_for_newframe_muted();
@@ -2144,6 +2197,42 @@ void softbody_bake(Object *ob)
allqueue(REDRAWBUTSOBJECT, 0);
}
+void pointcache_free(PTCacheID *pid, int cacheonly)
+{
+ Base *base;
+ ListBase pidlist;
+
+ if(pid) {
+ if(cacheonly)
+ BKE_ptcache_id_reset(pid, PTCACHE_RESET_DEPSGRAPH);
+ else
+ BKE_ptcache_id_reset(pid, PTCACHE_RESET_BAKED);
+
+ DAG_object_flush_update(G.scene, pid->ob, OB_RECALC_DATA);
+ }
+ else {
+ for(base=G.scene->base.first; base; base= base->next) {
+ if(TESTBASELIB(base)) {
+ BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+ for(pid=pidlist.first; pid; pid=pid->next) {
+ if(cacheonly)
+ BKE_ptcache_id_reset(pid, PTCACHE_RESET_DEPSGRAPH);
+ else
+ BKE_ptcache_id_reset(pid, PTCACHE_RESET_BAKED);
+
+ DAG_object_flush_update(G.scene, pid->ob, OB_RECALC_DATA);
+ }
+
+ BLI_freelistN(&pidlist);
+ }
+ }
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+}
+
// store processed path & file prefix for fluidsim bake directory
void fluidsimFilesel(char *selection)
{
@@ -2274,34 +2363,15 @@ void do_object_panels(unsigned short event)
allqueue(REDRAWVIEW3D, 0);
break;
- case B_SOFTBODY_CHANGE:
- ob= OBACT;
- if(ob) {
- ParticleSystem *psys = PE_get_current(ob);
- if(psys)
- psys->softflag |= OB_SB_REDO;
- else
- ob->softflag |= OB_SB_REDO;
- allqueue(REDRAWBUTSOBJECT, 0);
- allqueue(REDRAWVIEW3D, 0);
- }
- break;
case B_SOFTBODY_DEL_VG:
if(ob->soft) {
ob->soft->vertgroup= 0;
- ob->softflag |= OB_SB_REDO;
+ //ob->softflag |= OB_SB_REDO;
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWVIEW3D, 0);
}
break;
- case B_SOFTBODY_BAKE:
- if(ob->soft) softbody_bake(ob);
- break;
- case B_SOFTBODY_BAKE_FREE:
- if(ob->soft) sbObjectToSoftbody(ob);
- allqueue(REDRAWBUTSOBJECT, 0);
- allqueue(REDRAWVIEW3D, 0);
- break;
case B_FLUIDSIM_BAKE:
/* write config files (currently no simulation) */
fluidsimBake(ob);
@@ -2316,6 +2386,7 @@ void do_object_panels(unsigned short event)
part->type = PART_FLUID;
psys->part = part;
+ psys->pointcache = BKE_ptcache_add();
psys->flag |= PSYS_ENABLED;
ob->fluidsimSettings->type = OB_FLUIDSIM_PARTICLE;
@@ -2375,63 +2446,21 @@ void do_object_panels(unsigned short event)
group_relink_nla_objects(ob);
allqueue(REDRAWVIEW3D, 0);
break;
- case B_BAKEABLE_CHANGE:
- allqueue(REDRAWBUTSOBJECT, 0);
- allqueue(REDRAWVIEW3D, 0);
- break;
case B_OBJECT_IPOFLAG:
if(ob->ipo) ob->ipo->showkey= (ob->ipoflag & OB_DRAWKEY)?1:0;
allqueue(REDRAWVIEW3D, 0);
break;
- case B_CLOTH_CLEARCACHEALL:
- {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- if(clmd)
- {
- // do nothing in editmode
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
- break;
-
- /* force freeing because user wants */
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
-
- /*user wants to free all, so free whole cloth, this helps to start sim at later frame */
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
-
- CFRA= 1;
- update_for_newframe_muted();
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- cloth_clear_cache(ob, clmd, 0);
- allqueue(REDRAWBUTSOBJECT, 0);
- allqueue(REDRAWVIEW3D, 0);
- }
- }
- break;
- case B_CLOTH_CLEARCACHEFRAME:
- {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- if(clmd)
- {
- // do nothing in editmode
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
- break;
-
- /* force freeing because user wants */
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
-
- cloth_clear_cache(ob, clmd, MAX2(0.0,G.scene->r.cfra));
- // MAX2(1.0,G.scene->r.cfra + 1.0)
- allqueue(REDRAWBUTSOBJECT, 0);
- }
- }
- break;
case B_CLOTH_CHANGEPREROLL:
{
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
if(clmd)
{
+ PTCacheID pid;
+
+ BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
// do nothing in editmode
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
+ if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
break;
CFRA= 1;
@@ -2442,17 +2471,11 @@ void do_object_panels(unsigned short event)
}
}
break;
- case B_CLOTH_RENEW:
+ case B_BAKE_CACHE_CHANGE:
{
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
-
- if(clmd)
- {
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- allqueue(REDRAWBUTSOBJECT, 0);
- allqueue(REDRAWVIEW3D, 0);
- }
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWVIEW3D, 0);
}
break;
@@ -2833,6 +2856,7 @@ void do_effects_panels(unsigned short event)
ParticleSystemModifierData *psmd;
ParticleSystem *psys;
ParticleSettings *part;
+ LinkNode *node, *firstnode;
ID *id,*idtest;
int nr;
@@ -3013,6 +3037,8 @@ void do_effects_panels(unsigned short event)
short nr=0;
if(id==0){ /* no psys previously -> no modifier -> need to create that also */
psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+ psys->pointcache = BKE_ptcache_add();
+ psys->flag |= PSYS_ENABLED;
BLI_addtail(&ob->particlesystem,psys);
md= modifier_new(eModifierType_ParticleSystem);
@@ -3025,7 +3051,7 @@ void do_effects_panels(unsigned short event)
idtest->us++;
psys->part=(ParticleSettings*)idtest;
psys->totpart=0;
- psys->flag=PSYS_ENABLED|PSYS_CURRENT;
+ psys->flag= PSYS_ENABLED|PSYS_CURRENT;
psys->cfra=bsystem_time(ob,G.scene->r.cfra+1,0.0);
/* check need for dupliobjects */
@@ -3094,6 +3120,27 @@ void do_effects_panels(unsigned short event)
}
}
break;
+
+ case B_PART_ALLOC:
+ case B_PART_DISTR:
+ case B_PART_INIT:
+ case B_PART_RECALC:
+ case B_PART_ALLOC_CHILD:
+ case B_PART_DISTR_CHILD:
+ case B_PART_INIT_CHILD:
+ case B_PART_RECALC_CHILD:
+ if(psys) {
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ }
+ break;
+
+ /* there were separate update events before the pointcache refactor,
+ * now it only does a flush update which means it is recalculating
+ * more than strictly needed, but how to restore such partial updates
+ * i'm not sure - brecht. */
+#if 0
case B_PART_ALLOC:
case B_PART_ALLOC_CHILD:
if(psys){
@@ -3103,6 +3150,7 @@ void do_effects_panels(unsigned short event)
allqueue(REDRAWOOPS, 0);
}
break;
+
case B_PART_DISTR:
case B_PART_DISTR_CHILD:
if(psys){
@@ -3129,13 +3177,8 @@ void do_effects_panels(unsigned short event)
allqueue(REDRAWBUTSEDIT, 0);
}
break;
- case B_PART_RECALC:
- case B_PART_RECALC_CHILD:
- if(psys){
- psys_flush_settings(psys->part,0,event==B_PART_RECALC);
- allqueue(REDRAWOOPS, 0);
- }
/* no break! */
+#endif
case B_PART_REDRAW_DEPS:
if(event == B_PART_REDRAW_DEPS)
DAG_scene_sort(G.scene);
@@ -3155,13 +3198,17 @@ void do_effects_panels(unsigned short event)
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_PARTTYPE:
- if((psys=psys_get_current(ob))){
- DAG_scene_sort(G.scene);
+ if(psys) {
+ /* 1 = do DAG_object_flush_update */
+ firstnode= psys_using_settings(psys->part, 1);
- psys_flush_settings(psys->part,PSYS_TYPE,1);
+ for(node=firstnode; node; node=node->next)
+ psys_changed_type(node->link);
+
+ BLI_linklist_free(firstnode, NULL);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
}
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_PARTACT:
allqueue(REDRAWVIEW3D, 0);
@@ -3318,15 +3365,16 @@ static void object_collision__enabletoggle ( void *ob_v, void *arg2 )
}
/* Panels for particle interaction settings */
-static void object_panel_deflection(Object *ob)
+static void object_panel_collision(Object *ob)
{
uiBlock *block;
uiBut *but;
block= uiNewBlock(&curarea->uiblocks, "object_panel_deflection", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Deflection", "Physics", 0, 0, 318, 204)==0) return;
+ uiNewPanelTabbed("Fields", "Physics");
+ if(uiNewPanel(curarea, block, "Collision", "Physics", 0, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
/* should become button, option? */
if(ob->pd==NULL) {
@@ -3341,27 +3389,33 @@ static void object_panel_deflection(Object *ob)
if(ob->pd && ob->type==OB_MESH) {
PartDeflect *pd= ob->pd;
- but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
+ but = uiDefButBitS(block, TOG, 1, B_REDR, "Collision",10,160,150,20, &pd->deflect, 0, 0, 0, 0, "Enable this objects as a collider for physics systems");
uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
+
+ uiDefBut(block, LABEL, 0, "",160,160,150,2, NULL, 0.0, 0, 0, 0, "");
if(pd->deflect) {
- uiDefBut(block, LABEL, 0, "Particles", 160,140,75,20, NULL, 0.0, 0, 0, 0, "");
- uiDefButBitS(block, TOG, PDEFLE_KILL_PART, B_DIFF, "Kill",235,140,75,20, &pd->flag, 0, 0, 0, 0, "Kill collided particles");
+ uiDefBut(block, LABEL, 0, "Particle Interaction", 10,135,310,20, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_DIFF, "Damping: ", 160,120,75,20, &pd->pdef_damp, 0.0, 1.0, 10, 0, "Amount of damping during particle collision");
- uiDefButF(block, NUM, B_DIFF, "Rnd Damping: ", 235,120,75,20, &pd->pdef_rdamp, 0.0, 1.0, 10, 0, "Random variation of damping");
- uiDefButF(block, NUM, B_DIFF, "Friction: ", 160,100,75,20, &pd->pdef_frict, 0.0, 1.0, 10, 0, "Amount of friction during particle collision");
- uiDefButF(block, NUM, B_DIFF, "Rnd Friction: ", 235,100,75,20, &pd->pdef_rfrict, 0.0, 1.0, 10, 0, "Random variation of friction");
- uiDefButF(block, NUM, B_DIFF, "Permeability: ", 160,80,150,20, &pd->pdef_perm, 0.0, 1.0, 10, 0, "Chance that the particle will pass through the mesh");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping: ", 10,115,105,20, &pd->pdef_damp, 0.0, 1.0, 10, 2, "Amount of damping during particle collision");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Rnd: ", 115,115,75,20, &pd->pdef_rdamp, 0.0, 1.0, 10, 2, "Random variation of damping");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Friction: ", 10,95,105,20, &pd->pdef_frict, 0.0, 1.0, 10, 2, "Amount of friction during particle collision");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Rnd: ", 115,95,75,20, &pd->pdef_rfrict, 0.0, 1.0, 10, 2, "Random variation of friction");
uiBlockEndAlign(block);
+
+ uiDefButBitS(block, TOG, PDEFLE_KILL_PART, B_FIELD_CHANGE, "Kill",200,115,120,20, &pd->flag, 0, 0, 0, 0, "Kill collided particles");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Permeability: ", 200,90,120,20, &pd->pdef_perm, 0.0, 1.0, 10, 2, "Chance that the particle will pass through the mesh");
- uiDefBut(block, LABEL, 0, "Soft Body / Cloth", 160,60,150,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Soft Body and Cloth Interaction", 10,65,310,20, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:", 160,40,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during soft body collision");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:", 160,20,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:", 160, 0,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:", 10,45,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during collision");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:", 10,25,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:", 10, 5,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
+ uiBlockEndAlign(block);
+
+ uiDefButBitS(block, TOG, OB_SB_COLLFINAL, B_FIELD_CHANGE, "Ev.M.Stack", 170,45,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack (softbody only)");
}
}
}
@@ -3373,10 +3427,9 @@ static void object_panel_fields(Object *ob)
static short actpsys=-1;
block= uiNewBlock(&curarea->uiblocks, "object_panel_fields", UI_EMBOSS, UI_HELV, curarea->win);
- uiNewPanelTabbed("Deflection", "Physics");
if(uiNewPanel(curarea, block, "Fields", "Physics", 0, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
/* should become button, option? */
if(ob->pd==NULL) {
@@ -3391,6 +3444,8 @@ static void object_panel_fields(Object *ob)
PartDeflect *pd= ob->pd;
char *menustr= MEM_mallocN(256, "temp string");
char *tipstr="Choose field type";
+
+ uiBlockBeginAlign(block);
if(ob->particlesystem.first) {
ParticleSystem *psys;
@@ -3443,6 +3498,9 @@ static void object_panel_fields(Object *ob)
else
uiDefButS(block, MENU, B_FIELD_DEP, menustr, 10,180,140,20, &pd->forcefield, 0.0, 0.0, 0, 0, tipstr);
+ uiBlockEndAlign(block);
+ uiDefBut(block, LABEL, 0, "",160,180,150,2, NULL, 0.0, 0, 0, 0, "");
+
MEM_freeN(menustr);
if(pd->forcefield) {
@@ -3460,10 +3518,12 @@ static void object_panel_fields(Object *ob)
uiDefButF(block, NUM, B_FIELD_CHANGE, "Strength: ", 10,140,140,20, &pd->f_strength, -1000, 1000, 10, 3, "Strength of force field");
if(pd->forcefield == PFIELD_TEXTURE){
- uiDefIDPoinBut(block, field_testTexture, ID_TE, B_FIELD_CHANGE, "Texture: ", 10, 120, 140, 20, &pd->tex, "Texture to use as force");
- uiDefButBitS(block, TOG, PFIELD_TEX_OBJECT, B_FIELD_CHANGE, "Use Object Co", 10,100,140,20, &pd->flag, 0.0, 0, 0, 0, "Use object/global coordinates for texture");
- uiDefButBitS(block, TOG, PFIELD_TEX_ROOTCO, B_FIELD_CHANGE, "Root TexCo", 10,80,120,20, &pd->flag, 0.0, 0, 0, 0, "Texture coords from root particle locations");
- uiDefButBitS(block, TOG, PFIELD_TEX_2D, B_FIELD_CHANGE, "2D", 130,80,20,20, &pd->flag, 0.0, 0, 0, 0, "Apply force only in 2d");
+ uiDefIDPoinBut(block, field_testTexture, ID_TE, B_FIELD_CHANGE, "Texture: ", 10,120,140,20, &pd->tex, "Texture to use as force");
+ uiBlockEndAlign(block);
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PFIELD_TEX_OBJECT, B_FIELD_CHANGE, "Use Object Co", 10,95,140,20, &pd->flag, 0.0, 0, 0, 0, "Use object/global coordinates for texture");
+ uiDefButBitS(block, TOG, PFIELD_TEX_ROOTCO, B_FIELD_CHANGE, "Root TexCo", 10,75,100,20, &pd->flag, 0.0, 0, 0, 0, "Texture coords from root particle locations");
+ uiDefButBitS(block, TOG, PFIELD_TEX_2D, B_FIELD_CHANGE, "2D", 120,75,30,20, &pd->flag, 0.0, 0, 0, 0, "Apply force only in 2d");
}
else if(pd->forcefield == PFIELD_HARMONIC)
uiDefButF(block, NUM, B_FIELD_CHANGE, "Damp: ", 10,120,140,20, &pd->f_damp, 0, 10, 10, 0, "Damping of the harmonic force");
@@ -3475,13 +3535,13 @@ static void object_panel_fields(Object *ob)
uiDefButBitS(block, TOG, PFIELD_GUIDE_PATH_ADD, B_FIELD_CHANGE, "Additive", 10,40,140,20, &pd->flag, 0.0, 0, 0, 0, "Based on distance/falloff it adds a portion of the entire path");
}
else if(pd->forcefield==PFIELD_TEXTURE){
- uiDefButS(block, MENU, B_FIELD_CHANGE, "Texture mode%t|RGB%x0|Gradient%x1|Curl%x2", 10,40,140,20, &pd->tex_mode, 0.0, 0.0, 0, 0, "How the texture effect is calculated (RGB & Curl need a RGB texture else Gradient will be used instead)");
+ uiDefButS(block, MENU, B_FIELD_CHANGE, "Texture mode%t|RGB%x0|Gradient%x1|Curl%x2", 10,50,140,20, &pd->tex_mode, 0.0, 0.0, 0, 0, "How the texture effect is calculated (RGB & Curl need a RGB texture else Gradient will be used instead)");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Nabla:", 10,20,140,20, &pd->tex_nabla, 0.0001f, 1.0, 1, 0, "Specify the dimension of the area for gradient and curl calculation");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Nabla:", 10,30,140,20, &pd->tex_nabla, 0.0001f, 1.0, 1, 0, "Specify the dimension of the area for gradient and curl calculation");
}
else if(particles==0 && ELEM(pd->forcefield,PFIELD_VORTEX,PFIELD_WIND)==0){
//uiDefButF(block, NUM, B_FIELD_CHANGE, "Distance: ", 10,20,140,20, &pd->f_dist, 0, 1000.0, 10, 0, "Falloff power (real gravitational fallof = 2)");
- uiDefButBitS(block, TOG, PFIELD_PLANAR, B_FIELD_CHANGE, "Planar", 10,0,140,20, &pd->flag, 0.0, 0, 0, 0, "Create planar field");
+ uiDefButBitS(block, TOG, PFIELD_PLANAR, B_FIELD_CHANGE, "Planar", 10,15,140,20, &pd->flag, 0.0, 0, 0, 0, "Create planar field");
}
uiBlockEndAlign(block);
@@ -3542,30 +3602,159 @@ static void object_panel_fields(Object *ob)
}
}
+/* Generic physics baking buttons */
+
+static void object_physics__baketoggle(void *pid_v, void *unused_v)
+{
+ PTCacheID *pid = pid_v;
+ Object *ob = pid->ob;
+ PointCache *cache = pid->cache;
+ ClothModifierData *clmd;
+ int cageIndex, stack_index, startframe, endframe;
+
+ // automatically enable modifier in editmode when we have a protected cache
+ if(!(cache->flag & PTCACHE_BAKED)) {
+ BKE_ptcache_id_time(pid, 0.0f, &startframe, &endframe, NULL);
+ pointcache_bake(pid, startframe);
+
+ if(pid->type == PTCACHE_TYPE_CLOTH) {
+ clmd= (ClothModifierData*)pid->data;
+ cageIndex = modifiers_getCageIndex(ob, NULL );
+ stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
+ if(stack_index >= cageIndex)
+ ((ModifierData *)clmd)->mode ^= eModifierMode_OnCage;
+ }
+ }
+ else {
+ if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE) {
+ notice("Can't free bake in editmode");
+ }
+ else {
+ if(pid->type == PTCACHE_TYPE_CLOTH) {
+ clmd= (ClothModifierData*)pid->data;
+ ((ModifierData *)clmd)->mode ^= eModifierMode_OnCage;
+ }
+
+ cache->flag &= ~PTCACHE_BAKED;
+ BKE_ptcache_id_reset(pid, PTCACHE_RESET_OUTDATED);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+}
+
+static void object_physics__rebake(void *pid_v, void *unused_v)
+{
+ PTCacheID *pid = pid_v;
+ int curframe = (int)G.scene->r.cfra;
+
+ BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, curframe);
+ pointcache_bake(pid, curframe);
+}
+
+static void object_physics__clearcache(void *pid_v, void *unused_v)
+{
+ PTCacheID *pid = pid_v;
+ Object *ob = pid->ob;
+ PointCache *cache = pid->cache;
+
+ if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
+ return;
+
+ BKE_ptcache_id_reset(pid, PTCACHE_RESET_BAKED);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+static void object_physics_bake_buttons(uiBlock *block, PTCacheID *pid, int y, int libdata)
+{
+ uiBut *but;
+ PointCache *cache;
+
+ cache= pid->cache;
+
+ if(!libdata && G.obedit)
+ uiSetButLock(1, "Can't change bake settings in editmode");
+
+ if(cache->flag & PTCACHE_BAKED)
+ but = uiDefBut(block, BUT, REDRAWBUTSOBJECT, "Free Bake", 10,y+25,85,20, NULL, 0.0, 0.0, 0, 0, "Free baked simulation");
+ else
+ but = uiDefBut(block, BUT, REDRAWBUTSOBJECT, "Bake", 10,y+25,85,20, NULL, 0.0, 0.0, 0, 0, "Bake specified frame range");
+ uiButSetFunc(but, object_physics__baketoggle, pid, NULL);
+
+ if(!libdata && !G.obedit && (cache->flag & PTCACHE_BAKED))
+ uiSetButLock(1, "Simulation frames are baked");
+
+ uiBlockBeginAlign(block);
+ uiDefButI(block, NUM, B_BAKE_CACHE_CHANGE, "Start:", 100,y+25,105,20, &cache->startframe, 1, MAXFRAME, 1, 0, "Frame on which the simulation starts");
+ uiDefButI(block, NUM, B_BAKE_CACHE_CHANGE, "End:", 205,y+25,105,20, &cache->endframe, 1, MAXFRAME, 1, 0, "Frame on which the simulation stops");
+ uiBlockEndAlign(block);
+
+ if(cache->flag & PTCACHE_BAKED) {
+ if(pid->type == PTCACHE_TYPE_CLOTH ||
+ (pid->type == PTCACHE_TYPE_SOFTBODY && !((SoftBody*)pid->data)->particles)) {
+ if(!libdata && !G.obedit)
+ uiClearButLock();
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, PTCACHE_BAKE_EDIT, REDRAWVIEW3D, "Bake Editing", 10,y,100,20, &cache->flag, 0, 0, 0, 0, "Enable editing of the baked results in editmode.");
+ but= uiDefBut(block, BUT, REDRAWBUTSOBJECT, "Rebake From Current Frame", 110,y,200,20, NULL, 0.0, 0.0, 0, 0, "Bake again from current frame");
+ uiButSetFunc(but, object_physics__rebake, pid, NULL);
+ uiBlockEndAlign(block);
+ }
+
+ if(!libdata)
+ uiClearButLock();
+ }
+ else {
+ char str[512];
+ int exist, startframe, endframe;
+
+ if(!libdata)
+ uiClearButLock();
+
+ BKE_ptcache_id_time(pid, 0.0f, &startframe, &endframe, NULL);
+ exist= BKE_ptcache_id_exist(pid, startframe);
+
+ sprintf(str, "%simulation frames in disk cache.", (exist)? "S": "No s");
+ uiDefBut(block, LABEL, 0, str, 10,y,200,20, NULL, 0.0, 0, 0, 0, "");
+
+ if(exist) {
+ but= uiDefBut(block, BUT, REDRAWBUTSOBJECT, "Free Cache", 210,y,100,20, NULL, 0.0, 0.0, 0, 0, "Free cached simulation results");
+ uiButSetFunc(but, object_physics__clearcache, pid, NULL);
+ }
+ }
+}
+
/* Panel for softbodies */
static void object_softbodies__enable(void *ob_v, void *arg2)
{
Object *ob = ob_v;
ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody);
+ PTCacheID pid;
- if (modifiers_isSoftbodyEnabled(ob)) {
- if (md) {
- md->mode &= ~(eModifierMode_Render|eModifierMode_Realtime);
- }
- } else {
- if (!md) {
- md = modifier_new(eModifierType_Softbody);
- BLI_addhead(&ob->modifiers, md);
- }
+ if(md) {
+ BLI_remlink(&ob->modifiers, md);
+ modifier_free(md);
+ BIF_undo_push("Del modifier");
- md->mode |= eModifierMode_Render|eModifierMode_Realtime;
+ ob->softflag &= ~OB_SB_ENABLE;
+ } else {
+ md = modifier_new(eModifierType_Softbody);
+ BLI_addhead(&ob->modifiers, md);
if (!ob->soft) {
ob->soft= sbNew();
ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
- softbody_clear_cache(ob, CFRA);
+
+ BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
+ BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
}
+
+ ob->softflag |= OB_SB_ENABLE;
}
+
/* needed so that initial state is cached correctly */
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
@@ -3589,7 +3778,7 @@ static void object_softbodies__enable_psys(void *ob_v, void *psys_v)
ParticleSystem *psys = psys_v;
Object *ob = ob_v;
- if(psys->softflag & OB_SB_ENABLE){
+ if(psys->softflag & OB_SB_ENABLE) {
psys->softflag &= ~OB_SB_ENABLE;
}
else{
@@ -3597,7 +3786,6 @@ static void object_softbodies__enable_psys(void *ob_v, void *psys_v)
psys->soft= sbNew();
psys->softflag |= OB_SB_GOAL|OB_SB_EDGES;
psys->soft->particles=psys;
- clear_particles_from_cache(ob, psys, CFRA);
}
psys->softflag |= OB_SB_ENABLE;
}
@@ -3620,10 +3808,12 @@ static void object_softbodies_collision(Object *ob)
{
SoftBody *sb=ob->soft;
uiBlock *block;
- uiBut *but = NULL;
static int val;
short *softflag=&ob->softflag, psys_cur=0;
int ob_has_hair=psys_ob_has_hair(ob);
+ static PTCacheID staticpid;
+ int libdata;
+
if(!_can_softbodies_at_all(ob)) return;
/*bah that is ugly! creating missing data members in UI code*/
if(ob->pd == NULL){
@@ -3636,7 +3826,8 @@ static void object_softbodies_collision(Object *ob)
uiNewPanelTabbed("Soft Body", "Physics");
if(uiNewPanel(curarea, block, "Soft Body Collision", "Physics", 651, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ libdata= object_is_libdata(ob);
+ uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
if(ob_has_hair) {
if(PE_get_current_num(ob) >= 0) {
@@ -3662,64 +3853,43 @@ static void object_softbodies_collision(Object *ob)
uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
uiBlockBeginAlign(block);
if(psys_cur){
- uiDefBut(block, LABEL, 0, "Hair is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "However the emitter can deflect a softbody",10,170,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Hair is not a softbody.",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
}
else {
- uiDefBut(block, LABEL, 0, "Object is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "However it can deflect a softbody",10,170,300,20, NULL, 0.0, 0, 0, 0, "");
- }
- /* OTHER OBJECTS COLLISION STUFF */
- if (ob->type==OB_MESH){
- uiBlockBeginAlign(block);
- but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",10,50,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Makes this object visible to softbody objects");
- uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
- if(ob->pd->deflect) {
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:", 160,50,150,20, &ob->pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during soft body collision");
- uiDefButBitS(block, TOG,OB_SB_COLLFINAL , B_DIFF, "Ev.M.Stack",10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:", 160,30,150,20, &ob->pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:", 160,10,150,20, &ob->pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
- }
+ uiDefBut(block, LABEL, 0, "Object is not a softbody.",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
}
uiBlockEndAlign(block);
}
else{
+ BKE_ptcache_id_from_softbody(&staticpid, ob, sb);
+ object_physics_bake_buttons(block, &staticpid, 125, libdata);
+
/* SELF COLLISION STUFF */
if ((ob->type==OB_MESH)||(ob->type==OB_CURVE) ) {
uiBlockBeginAlign(block);
if (*softflag & OB_SB_EDGES){
- uiDefButBitS(block, TOG, OB_SB_SELF, B_SOFTBODY_CHANGE, "Self Collision", 10,170,150,20, softflag, 0, 0, 0, 0, "enable naive vertex ball self collision");
+ uiDefButBitS(block, TOG, OB_SB_SELF, B_BAKE_CACHE_CHANGE, "Self Collision", 10,80,150,20, softflag, 0, 0, 0, 0, "enable naive vertex ball self collision");
if(*softflag & OB_SB_SELF){
- uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Ball Size:", 160,170,150,20, &sb->colball, -10.0, 10.0, 10, 0, "Absolute ball size or factor if not manual adjusted");
- uiDefButS(block, ROW, B_DIFF, "Man",10,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MANUAL, 0, 0, "Manual adjust");
- uiDefButS(block, ROW, B_DIFF, "Av",70,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_AVG, 0, 0, "Average Spring lenght * Ball Size");
- uiDefButS(block, ROW, B_DIFF, "Min",130,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MIN, 0, 0, "Minimal Spring lenght * Ball Size");
- uiDefButS(block, ROW, B_DIFF, "Max",190,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MAX, 0, 0, "Maximal Spring lenght * Ball Size");
- uiDefButS(block, ROW, B_DIFF, "AvMiMa",250,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_AVGMINMAX, 0, 0, "(Min+Max)/2 * Ball Size");
- uiDefButF(block, NUM, B_DIFF, "B Stiff:", 10,130,150,20, &sb->ballstiff, 0.001, 100.0, 10, 0, "Ball inflating presure");
- uiDefButF(block, NUM, B_DIFF, "B Damp:", 160,130,150,20, &sb->balldamp, 0.001, 1.0, 10, 0, "Blending to inelastic collision");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Ball Size:", 160,80,150,20, &sb->colball, -10.0, 10.0, 10, 0, "Absolute ball size or factor if not manual adjusted");
+ uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "Man",10,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MANUAL, 0, 0, "Manual adjust");
+ uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "Av",70,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_AVG, 0, 0, "Average Spring lenght * Ball Size");
+ uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "Min",130,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MIN, 0, 0, "Minimal Spring lenght * Ball Size");
+ uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "Max",190,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MAX, 0, 0, "Maximal Spring lenght * Ball Size");
+ uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "AvMiMa",250,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_AVGMINMAX, 0, 0, "(Min+Max)/2 * Ball Size");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "B Stiff:", 10,40,150,20, &sb->ballstiff, 0.001, 100.0, 10, 0, "Ball inflating presure");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "B Damp:", 160,40,150,20, &sb->balldamp, 0.001, 1.0, 10, 0, "Blending to inelastic collision");
}
}
else{
- uiDefBut(block, LABEL, 0, "<Self Collision> not available because there",10,170,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "are no edges, enable <Use Edges>",10,150,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "<Self Collision> not available because there",10,80,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "are no edges, enable <Use Edges>",10,60,300,20, NULL, 0.0, 0, 0, 0, "");
}
uiBlockEndAlign(block);
/*SOLVER SETTINGS*/
/* done in another panel now*/
}
- /* OTHER OBJECTS COLLISION STUFF */
- if (ob->type==OB_MESH){
- but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",10,50,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Makes this object visible to other softbody objects");
- uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
- if(ob->pd->deflect) {
- uiDefButF(block, NUM, B_DIFF, "Damping:", 160,50,150,20, &ob->pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during soft body collision");
- uiDefButBitS(block, TOG,OB_SB_COLLFINAL , B_DIFF, "Ev.M.Stack",10,30,150,20, softflag, 0, 0, 0, 0, "Pick collision object from modifier stack");
- uiDefButF(block, NUM, B_DIFF, "Inner:", 160,30,150,20, &ob->pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
- uiDefButF(block, NUM, B_DIFF, "Outer:", 160,10,150,20, &ob->pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
- }
- }
+
uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
}
uiBlockEndAlign(block);
@@ -3736,7 +3906,8 @@ static void object_softbodies_solver(Object *ob)
uiNewPanelTabbed("Soft Body", "Physics");
if(uiNewPanel(curarea, block, "Soft Body Solver", "Physics", 651, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
/* doubt that is really needed here but for now */
if(ob_has_hair) {
if(PE_get_current_num(ob) >= 0) {
@@ -3761,10 +3932,10 @@ static void object_softbodies_solver(Object *ob)
if(!val) {
uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
if(psys_cur){
- uiDefBut(block, LABEL, 0, "Hair is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Hair is not a softbody.",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
}
else {
- uiDefBut(block, LABEL, 0, "Object is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Object is not a softbody.",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
}
}
else{
@@ -3772,7 +3943,7 @@ static void object_softbodies_solver(Object *ob)
/*SOLVER SETTINGS*/
uiBlockBeginAlign(block);
uiDefBut(block, LABEL, 0, "Solver select",10,200,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,180,300,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
+ uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, sbsolvers,10,180,300,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
uiBlockEndAlign(block);
/*some have adapive step size - some not*/
@@ -3787,31 +3958,31 @@ static void object_softbodies_solver(Object *ob)
if(adaptive_mode){
uiBlockBeginAlign(block);
uiDefBut(block, LABEL, 0, "Step size controls",10,160,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_DIFF, "Error Lim:", 10,140,280,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
- uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"V", 290,140,20,20, &sb->solverflags, 0, 0, 0, 0, "Use velocities for automagic step sizes");
- uiDefButS(block, NUM, B_DIFF, "MinS:", 10,120,150,20, &sb->minloops, 0.00, 30000.0, 10, 0, "Minimal # solver steps/frame ");
- uiDefButS(block, NUM, B_DIFF, "MaxS:", 160,120,150,20, &sb->maxloops, 0.00, 30000.0, 10, 0, "Maximal # solver steps/frame ");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Error Lim:", 10,140,280,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
+ uiDefButBitS(block, TOG, SBSO_OLDERR, B_BAKE_CACHE_CHANGE,"V", 290,140,20,20, &sb->solverflags, 0, 0, 0, 0, "Use velocities for automagic step sizes");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "MinS:", 10,120,150,20, &sb->minloops, 0.00, 30000.0, 10, 0, "Minimal # solver steps/frame ");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "MaxS:", 160,120,150,20, &sb->maxloops, 0.00, 30000.0, 10, 0, "Maximal # solver steps/frame ");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefBut(block, LABEL, 0, "Collision helpers",10,100,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefButS(block, NUM, B_DIFF, "Choke:", 10,80,150,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
- uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 160,80,150,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Choke:", 10,80,150,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Fuzzy:", 160,80,150,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefBut(block, LABEL, 0, "Diagnosis",10,60,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"Print Performance to Console", 10,40,300,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
+ uiDefButBitS(block, TOG, SBSO_MONITOR, B_BAKE_CACHE_CHANGE,"Print Performance to Console", 10,40,300,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
uiBlockEndAlign(block);
}
else{
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 210,100,90,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
- uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 290,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Fuzzy:", 210,100,90,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+ uiDefButBitS(block, TOG, SBSO_MONITOR, B_BAKE_CACHE_CHANGE,"M", 290,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
uiBlockEndAlign(block);
- uiDefButS(block, NUM, B_DIFF, "Steps:", 10,80,100,20, &sb->minloops, 1.00, 30000.0, 10, 0, "Solver steps/frame ");
- uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Steps:", 10,80,100,20, &sb->minloops, 1.00, 30000.0, 10, 0, "Solver steps/frame ");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Choke:", 210,80,100,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
}
uiBlockEndAlign(block);
@@ -3821,22 +3992,13 @@ static void object_softbodies_solver(Object *ob)
uiBlockEndAlign(block);
}
-static void sb_clear_cache(void *ob_v, void *actsoft_v)
-{
- Object *ob = ob_v;
- short *actsoft = actsoft_v;
-
- if(actsoft)
- clear_particles_from_cache(ob, BLI_findlink(&ob->particlesystem, *actsoft), CFRA);
- else
- softbody_clear_cache(ob, CFRA);
-}
static void object_softbodies(Object *ob)
{
SoftBody *sb=ob->soft;
ParticleSystem *psys=NULL;
uiBlock *block;
uiBut *but;
+ ModifierData *md;
static int val;
short *softflag=&ob->softflag, psys_cur=0;
int ob_has_hair = psys_ob_has_hair(ob);
@@ -3846,12 +4008,11 @@ static void object_softbodies(Object *ob)
block= uiNewBlock(&curarea->uiblocks, "object_softbodies", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Soft Body", "Physics");
if(uiNewPanel(curarea, block, "Soft Body", "Physics", 640, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
if(ob_has_hair) {
- char *menustr = psys_menu_string(ob,1);
-
psys= psys_get_current(ob);
+
if(psys && actsoft >= 0) {
actsoft= psys_get_current_num(ob)+1;
@@ -3861,52 +4022,56 @@ static void object_softbodies(Object *ob)
}
else
actsoft= -1; /* -1 = object */
-
- but=uiDefButS(block, MENU, B_BAKE_REDRAWEDIT, menustr, 10,200,100,20, &actsoft, 14.0, 0.0, 0, 0, "Browse systems");
- uiButSetFunc(but, PE_change_act, ob, &actsoft);
-
- MEM_freeN(menustr);
}
- if(psys_cur && psys){
+ if(psys_cur && psys) {
if(*softflag & OB_SB_ENABLE)
- val=1;
+ val = 1;
else
- val=0;
+ val = 0;
- but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 110,200,70,20, &val, 0, 0, 0, 0, "Sets hair to become soft body");
+ but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 10,200,130,20, &val, 0, 0, 0, 0, "Sets hair to become soft body");
uiButSetFunc(but, object_softbodies__enable_psys, ob, psys);
}
- else{
- val = modifiers_isSoftbodyEnabled(ob);
+ else {
+ md = modifiers_findByType(ob, eModifierType_Softbody);
+ val = (md != NULL);
+
if(ob_has_hair)
- but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 110,200,70,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
+ but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
else
but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
-
uiButSetFunc(but, object_softbodies__enable, ob, NULL);
+
+ if(md) {
+ uiBlockBeginAlign(block);
+ uiDefIconButBitI(block, TOG, eModifierMode_Render, B_BAKE_CACHE_CHANGE, ICON_SCENE, 145, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable soft body during rendering");
+ but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_BAKE_CACHE_CHANGE, VICON_VIEW3D, 165, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable soft body during interactive display");
+ uiBlockEndAlign(block);
+ }
}
+
+ if(ob_has_hair) {
+ char *menustr = psys_menu_string(ob,1);
+
+ but=uiDefButS(block, MENU, B_BAKE_REDRAWEDIT, menustr, 210,200,100,20, &actsoft, 14.0, 0.0, 0, 0, "Browse systems");
+ uiButSetFunc(but, PE_change_act, ob, &actsoft);
+
+ MEM_freeN(menustr);
+ }
+
+
uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
- if(val){
+ if(val) {
int defCount;
char *menustr;
static char str[128];
- //uiDefButBitS(block, TOG, OB_SB_BAKESET, REDRAWBUTSOBJECT, "Bake settings", 180,200,130,20, &ob->softflag, 0, 0, 0, 0, "To convert simulation into baked (cached) result");
-
- //if(sb->keys) uiSetButLock(1, "Soft Body is baked, free it first");
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, OB_SB_PROTECT_CACHE, REDRAWBUTSOBJECT, "Protect", 180,200,50,20, softflag, 0.0, 0.0, 10, 0, "Protect the cache");
- but=uiDefBut(block, BUT, B_SOFTBODY_CHANGE, "Clear", 230,200,50,20, NULL, 0.0, 0.0, 10, 0, "Clear the cache");
- if((*softflag & PSYS_PROTECT_CACHE)==0)
- uiButSetFunc(but, sb_clear_cache, ob, &actsoft);
-
- uiBlockEndAlign(block);
-
- if(*softflag & OB_SB_PROTECT_CACHE) uiSetButLock(1, "Cache is protected");
+ if(sb->pointcache->flag & PTCACHE_BAKED)
+ uiSetButLock(1, "Simulation frames are baked");
//if(ob->softflag & OB_SB_BAKESET) {
// uiBlockBeginAlign(block);
@@ -3939,66 +4104,66 @@ static void object_softbodies(Object *ob)
sprintf(str, "Vertex Mass");
}
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_DIFF, "Friction:", 10, 170,150,20, &sb->mediafrict, 0.0, 50.0, 10, 0, "General media friction for point movements");
- uiDefButF(block, NUM, B_DIFF, "Mass:", 160, 170,150,20, &sb->nodemass , 0.001, 50000.0, 10, 0, str);
- uiDefButF(block, NUM, B_DIFF, "Grav:", 10,150,150,20, &sb->grav , -10.0, 10.0, 10, 0, "Apply gravitation to point movement");
- uiDefButF(block, NUM, B_DIFF, "Speed:", 160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Friction:", 10, 170,150,20, &sb->mediafrict, 0.0, 50.0, 10, 0, "General media friction for point movements");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Mass:", 160, 170,150,20, &sb->nodemass , 0.001, 50000.0, 10, 0, str);
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Grav:", 10,150,150,20, &sb->grav , -10.0, 10.0, 10, 0, "Apply gravitation to point movement");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Speed:", 160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
uiBlockEndAlign(block);
/* GOAL STUFF */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, OB_SB_GOAL, B_SOFTBODY_CHANGE, "Use Goal", 10,120,130,20, softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
+ uiDefButBitS(block, TOG, OB_SB_GOAL, B_BAKE_CACHE_CHANGE, "Use Goal", 10,120,130,20, softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
if (*softflag & OB_SB_GOAL){
if(ob->type==OB_MESH) {
menustr= get_vertexgroup_menustr(ob);
defCount=BLI_countlist(&ob->defbase);
if(defCount==0) sb->vertgroup= 0;
- uiDefButS(block, MENU, B_SOFTBODY_CHANGE, menustr, 140,120,20,20, &sb->vertgroup, 0, defCount, 0, 0, "Browses available vertex groups");
+ uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, menustr, 140,120,20,20, &sb->vertgroup, 0, defCount, 0, 0, "Browses available vertex groups");
MEM_freeN (menustr);
if(sb->vertgroup) {
bDeformGroup *defGroup = BLI_findlink(&ob->defbase, sb->vertgroup-1);
if(defGroup)
- uiDefBut(block, BUT, B_DIFF, defGroup->name, 160,120,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
+ uiDefBut(block, BUT, B_BAKE_CACHE_CHANGE, defGroup->name, 160,120,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
else
- uiDefBut(block, BUT, B_DIFF, "(no group)", 160,120,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
+ uiDefBut(block, BUT, B_BAKE_CACHE_CHANGE, "(no group)", 160,120,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
uiDefIconBut(block, BUT, B_SOFTBODY_DEL_VG, ICON_X, 290,120,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group");
}
else
- uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Goal:", 160,120,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Goal:", 160,120,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
}
else {
- uiDefButS(block, TOG, B_SOFTBODY_CHANGE, "W", 140,120,20,20, &sb->vertgroup, 0, 1, 0, 0, "Use control point weight values");
- uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Goal:", 160,120,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
+ uiDefButS(block, TOG, B_BAKE_CACHE_CHANGE, "W", 140,120,20,20, &sb->vertgroup, 0, 1, 0, 0, "Use control point weight values");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Goal:", 160,120,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
}
- uiDefButF(block, NUM, B_DIFF, "G Stiff:", 10,100,150,20, &sb->goalspring, 0.0, 0.999, 10, 0, "Goal (vertex target position) spring stiffness");
- uiDefButF(block, NUM, B_DIFF, "G Damp:", 160,100,150,20, &sb->goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
- uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "G Min:", 10,80,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
- uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "G Max:", 160,80,150,20, &sb->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Stiff:", 10,100,150,20, &sb->goalspring, 0.0, 0.999, 10, 0, "Goal (vertex target position) spring stiffness");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Damp:", 160,100,150,20, &sb->goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Min:", 10,80,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Max:", 160,80,150,20, &sb->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
}
uiBlockEndAlign(block);
/* EDGE SPRING STUFF */
if(ob->type!=OB_SURF) {
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges", 10,50,90,20, softflag, 0, 0, 0, 0, "Use Edges as springs");
+ uiDefButBitS(block, TOG, OB_SB_EDGES, B_BAKE_CACHE_CHANGE, "Use Edges", 10,50,90,20, softflag, 0, 0, 0, 0, "Use Edges as springs");
if (*softflag & OB_SB_EDGES){
- uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 110,50,90,20, softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
- uiDefButBitS(block, TOG, OB_SB_EDGECOLL, B_DIFF, "CEdge", 220,50,45,20, softflag, 0, 0, 0, 0, "Edge collide too");
- uiDefButBitS(block, TOG, OB_SB_FACECOLL, B_DIFF, "CFace", 265,50,45,20, softflag, 0, 0, 0, 0, "Faces collide too SLOOOOOW warning ");
- uiDefButF(block, NUM, B_DIFF, "Pull:", 10,30,75,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness when longer than rest length");
- uiDefButF(block, NUM, B_DIFF, "Push:", 85,30,75,20, &sb->inpush, 0.0, 0.999, 10, 0, "Edge spring stiffness when shorter than rest length");
- uiDefButF(block, NUM, B_DIFF, "Damp:", 160,30,70,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction");
- uiDefButS(block, NUM, B_SOFTBODY_CHANGE, "SL:",250 ,30,60,20, &sb->springpreload, 0.0, 200.0, 10, 0, "Alter spring lenght to shrink/blow up (unit %) 0 to disable ");
-
- uiDefButBitS(block, TOG,OB_SB_AERO_ANGLE,B_SOFTBODY_CHANGE, "N",10,10,20,20, softflag, 0, 0, 0, 0, "New aero(uses angle and length)");
- uiDefButS(block, NUM, B_DIFF, "Aero:", 30,10,60,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "Make edges 'sail'");
- uiDefButS(block, NUM, B_SOFTBODY_CHANGE, "Plas:", 90,10,60,20, &sb->plastic, 0.0, 100.0, 10, 0, "Permanent deform");
+ uiDefButBitS(block, TOG, OB_SB_QUADS, B_BAKE_CACHE_CHANGE, "Stiff Quads", 110,50,90,20, softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
+ uiDefButBitS(block, TOG, OB_SB_EDGECOLL, B_BAKE_CACHE_CHANGE, "CEdge", 220,50,45,20, softflag, 0, 0, 0, 0, "Edge collide too");
+ uiDefButBitS(block, TOG, OB_SB_FACECOLL, B_BAKE_CACHE_CHANGE, "CFace", 265,50,45,20, softflag, 0, 0, 0, 0, "Faces collide too SLOOOOOW warning ");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Pull:", 10,30,75,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness when longer than rest length");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Push:", 85,30,75,20, &sb->inpush, 0.0, 0.999, 10, 0, "Edge spring stiffness when shorter than rest length");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Damp:", 160,30,70,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "SL:",250 ,30,60,20, &sb->springpreload, 0.0, 200.0, 10, 0, "Alter spring lenght to shrink/blow up (unit %) 0 to disable ");
+
+ uiDefButBitS(block, TOG,OB_SB_AERO_ANGLE,B_BAKE_CACHE_CHANGE, "N",10,10,20,20, softflag, 0, 0, 0, 0, "New aero(uses angle and length)");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Aero:", 30,10,60,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "Make edges 'sail'");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Plas:", 90,10,60,20, &sb->plastic, 0.0, 100.0, 10, 0, "Permanent deform");
if(ob->type==OB_MESH) {
- uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Be:", 150,10,80,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Bendig Stiffness");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Be:", 150,10,80,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Bendig Stiffness");
if (*softflag & OB_SB_QUADS){
- uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Sh:", 230,10,80,20, &sb->shearstiff, 0.0, 1.0, 10, 0, "Shear Stiffness");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Sh:", 230,10,80,20, &sb->shearstiff, 0.0, 1.0, 10, 0, "Shear Stiffness");
}
}
else sb->secondspring = 0;
@@ -4011,6 +4176,28 @@ static void object_softbodies(Object *ob)
uiBlockEndAlign(block);
}
+static void object_panel_particle_bake(Object *ob)
+{
+ uiBlock *block;
+ ParticleSystem *psys= psys_get_current(ob);
+ static PTCacheID staticpid;
+ int libdata;
+
+ if (psys==NULL || psys->part==NULL) return;
+ if (ELEM(psys->part->type, PART_HAIR, PART_FLUID)) return;
+ if (psys->part->phystype == PART_PHYS_KEYED) return;
+
+ block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_bake", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Particle System", "Particle");
+ if(uiNewPanel(curarea, block, "Bake", "Particle", 320, 0, 318, 204)==0) return;
+
+ libdata= object_is_libdata(ob);
+ uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
+
+ BKE_ptcache_id_from_particles(&staticpid, ob, psys);
+ object_physics_bake_buttons(block, &staticpid, 10, libdata);
+}
+
/* Panels for new particles*/
static void object_panel_particle_children(Object *ob)
{
@@ -4025,8 +4212,10 @@ static void object_panel_particle_children(Object *ob)
if(part==NULL) return;
block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_child", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Children", "Particle", 1300, 0, 318, 204)==0) return;
uiNewPanelTabbed("Extras", "Particle");
+ if(uiNewPanel(curarea, block, "Children", "Particle", 1300, 0, 318, 204)==0) return;
+
+ uiSetButLock((part->id.lib != NULL), ERROR_LIBDATA_MESSAGE);
if(part->type == PART_FLUID) {
uiDefBut(block, LABEL, 0, "No settings for fluid particles", butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, "");
@@ -4037,7 +4226,7 @@ static void object_panel_particle_children(Object *ob)
if(part->childtype==0) return;
- if(part->childtype==PART_CHILD_FACES && (psys->flag&(PSYS_HAIR_DONE|PSYS_KEYED))==0) {
+ if(part->childtype==PART_CHILD_FACES && !(part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR)) {
uiDefBut(block, LABEL, 0, "Hair or keyed", butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "particles needed!", butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
return;
@@ -4083,12 +4272,12 @@ static void object_panel_particle_children(Object *ob)
butx=160;
buty=180;
- if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED))
+ if(part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR)
uiDefButBitS(block, TOG, 1, B_PART_REDRAW, "Kink/Branch", butx,(buty-=buth),butw,buth, &kink_ui, 0, 0, 0, 0, "Show kink and branch options");
else
buty-=buth;
- if(kink_ui || (psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)) == 0) {
+ if(kink_ui || !(part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR)) {
buty -= buth/2;
/* kink */
@@ -4106,7 +4295,7 @@ static void object_panel_particle_children(Object *ob)
}
uiBlockEndAlign(block);
- if(part->childtype==PART_CHILD_PARTICLES && psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)) {
+ if(part->childtype==PART_CHILD_PARTICLES && (part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR)) {
if(part->flag & PART_BRANCHING) {
uiDefButBitI(block, TOG, PART_BRANCHING, B_PART_RECALC_CHILD, "Branching", butx,(buty-=2*buth),butw,buth, &part->flag, 0, 0, 0, 0, "Branch child paths from eachother");
uiDefButBitI(block, TOG, PART_ANIM_BRANCHING, B_PART_RECALC_CHILD, "Animated", butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Animate branching");
@@ -4183,6 +4372,8 @@ static void object_panel_particle_extra(Object *ob)
block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_extra", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Extras", "Particle", 980, 0, 318, 204)==0) return;
+ uiSetButLock((part->id.lib != NULL), ERROR_LIBDATA_MESSAGE);
+
if(part->type == PART_FLUID) {
uiDefBut(block, LABEL, 0, "No settings for fluid particles", butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, "");
return;
@@ -4363,7 +4554,7 @@ static void object_panel_particle_visual(Object *ob)
uiDefButF(block, NUM, B_PART_REDRAW, "Front:", butx,(buty-=buth),butw,buth, &part->draw_line[1], 0.0, 10.0, 0, 0, "Length of the line's head");
break;
case PART_DRAW_PATH:
- if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)) {
+ if(part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR) {
uiDefButS(block, NUM, B_PART_RECALC, "Steps:", butx,(buty+=buth),butw,buth, &part->draw_step, 0.0, 7.0, 0, 0, "How many steps paths are drawn with (power of 2)");
uiDefButS(block, NUM, B_PART_REDRAW, "Render:", butx,(buty-=buth),butw,buth, &part->ren_step, 0.0, 9.0, 0, 0, "How many steps paths are rendered with (power of 2)");
@@ -4484,11 +4675,12 @@ static void object_panel_particle_physics(Object *ob)
return;
}
- if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
-
- if(psys->flag & PSYS_EDITED || psys->flag & PSYS_PROTECT_CACHE) {
- uiSetButLock(1, "Hair is edited or cache is protected!");
- }
+ if(ob->id.lib)
+ uiSetButLock(1, "Can't edit library data");
+ else if(psys->flag & PSYS_EDITED)
+ uiSetButLock(1, "Hair is edited!");
+ else if(psys->pointcache->flag & PTCACHE_BAKED)
+ uiSetButLock(1, "Simulation frames are baked!");
if(part->phystype==PART_PHYS_KEYED){
uiBlockBeginAlign(block);
@@ -4641,10 +4833,6 @@ static void object_panel_particle_physics(Object *ob)
}
}
-static void psys_clear_cache(void *ob_v, void *psys_v)
-{
- clear_particles_from_cache((Object *)ob_v, (ParticleSystem *)psys_v, CFRA);
-}
static void object_panel_particle_system(Object *ob)
{
uiBlock *block;
@@ -4652,10 +4840,11 @@ static void object_panel_particle_system(Object *ob)
ParticleSystem *psys=NULL;
ParticleSettings *part;
ID *id, *idfrom;
+ ModifierData *md;
short butx=0, buty=160, butw=150, buth=20;
- char str[30];
+ char str[30], *lockmessage= NULL;
static short partact;
- short totpart, lock;
+ short totpart, lock= 0;
block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_system", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Particle System", "Particle", 0, 0, 318, 204)==0) return;
@@ -4685,7 +4874,7 @@ static void object_panel_particle_system(Object *ob)
partact=psys_get_current_num(ob)+1;
totpart=BLI_countlist(&ob->particlesystem);
sprintf(str, "%d Part", totpart);
- but=uiDefButS(block, NUM, B_PARTACT, str, 224,buty,88,buth, &partact, 1.0, totpart+1, 0, 0, "Shows the number of particle systems in the object and the active particle system");
+ but=uiDefButS(block, NUM, B_PARTACT, str, 230,buty,83,buth, &partact, 1.0, totpart+1, 0, 0, "Shows the number of particle systems in the object and the active particle system");
uiButSetFunc(but, PE_change_act, ob, &partact);
if(psys==NULL)
@@ -4697,38 +4886,43 @@ static void object_panel_particle_system(Object *ob)
return;
butx=0;
- buty-=5;
if(part->type == PART_FLUID) {
- uiDefButBitI(block, TOG, PSYS_ENABLED, B_PART_ENABLE, "Enabled", 0, buty+5, 100,buth, &psys->flag, 0, 0, 0, 0, "Sets particle system to be calculated and shown");
- uiDefBut(block, LABEL, 0, "No settings for fluid particles", butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "No settings for fluid particles", butx,buty,2*butw,buth, NULL, 0.0, 0, 0, 0, "");
return;
}
- else
- uiDefButBitI(block, TOG, PSYS_ENABLED, B_PART_ENABLE, "Enabled", 0,(buty-=buth),100,buth, &psys->flag, 0, 0, 0, 0, "Sets particle system to be calculated and shown");
+
+ buty -= (buth+5);
if(part->type == PART_HAIR){
if(psys->flag & PSYS_EDITED)
- uiDefBut(block, BUT, B_PART_EDITABLE, "Free Edit", 105,buty,100,buth, NULL, 0.0, 0.0, 10, 0, "Free editing");
+ uiDefBut(block, BUT, B_PART_EDITABLE, "Free Edit", butx+butw+10,buty,butw,buth, NULL, 0.0, 0.0, 10, 0, "Free editing");
else
- uiDefBut(block, BUT, B_PART_EDITABLE, "Set Editable", 105,buty,100,buth, NULL, 0.0, 0.0, 10, 0, "Finalize hair to enable editing in particle mode");
+ uiDefBut(block, BUT, B_PART_EDITABLE, "Set Editable", butx+butw+10,buty,butw,buth, NULL, 0.0, 0.0, 10, 0, "Finalize hair to enable editing in particle mode");
}
- else {
- uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, PSYS_PROTECT_CACHE, B_PART_REDRAW, "Protect", 105,buty,50,buth, &psys->flag, 0.0, 0.0, 10, 0, "Protect the cache");
- but=uiDefBut(block, BUT, B_PART_RECALC, "Clear", 155,buty,50,buth, NULL, 0.0, 0.0, 10, 0, "Clear the cache");
- if((psys->flag & PSYS_PROTECT_CACHE)==0)
- uiButSetFunc(but, psys_clear_cache, ob, &partact);
- uiBlockEndAlign(block);
+ if(psys->flag & PSYS_EDITED) {
+ lockmessage= "Hair is edited!";
+ lock= 1;
+ }
+ else if(psys->pointcache->flag & PTCACHE_BAKED) {
+ lockmessage= "Simulation frames are baked!";
+ lock= 1;
}
- lock= (psys->flag & PSYS_EDITED || psys->flag & PSYS_PROTECT_CACHE);
if(lock)
- uiSetButLock(1, "Hair is edited or cache is protected!");
+ uiSetButLock(1, lockmessage);
+
+ uiDefButS(block, MENU, B_PARTTYPE, "Type%t|Hair%x2|Reactor%x1|Emitter%x0", butx,buty,butw-45,buth, &part->type, 14.0, 0.0, 0, 0, "Type of particle system");
- uiDefButS(block, MENU, B_PARTTYPE, "Type%t|Hair%x2|Reactor%x1|Emitter%x0", 210,buty,100,buth, &part->type, 14.0, 0.0, 0, 0, "Type of particle system");
+ md= (ModifierData*)psys_get_modifier(ob, psys);
+ if(md) {
+ uiBlockBeginAlign(block);
+ uiDefIconButBitI(block, TOG, eModifierMode_Render, B_PART_RECALC, ICON_SCENE, butx+butw-40, buty, 20, 20,&md->mode, 0, 0, 1, 0, "Enable particle system during rendering");
+ but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_PART_RECALC, VICON_VIEW3D, butx+butw-20, buty, 20, 20,&md->mode, 0, 0, 1, 0, "Enable particle system during interactive display");
+ uiBlockEndAlign(block);
+ }
buty-=5;
uiDefBut(block, LABEL, 0, "Basic:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
@@ -4775,7 +4969,7 @@ static void object_panel_particle_system(Object *ob)
if(lock) uiClearButLock();
uiDefButBitI(block, TOG, PART_TRAND, B_PART_DISTR, "Random", butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Emit in random order of elements");
- if(lock) uiSetButLock(1, "Hair is edited or cache is protected!");
+ if(lock) uiSetButLock(1, lockmessage);
if(part->type==PART_REACTOR)
uiDefButS(block, MENU, B_PART_DISTR, "Particle %x3|Volume %x2|Faces %x1|Verts %x0", butx+butw/2,buty,butw/2,buth, &part->from, 14.0, 0.0, 0, 0, "Where to emit particles from");
@@ -4785,7 +4979,7 @@ static void object_panel_particle_system(Object *ob)
if(ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)) {
if(lock) uiClearButLock();
uiDefButBitI(block, TOG, PART_EDISTR, B_PART_DISTR, "Even",butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Use even distribution from faces based on face areas or edge lengths");
- if(lock) uiSetButLock(1, "Hair is edited or cache is protected!");
+ if(lock) uiSetButLock(1, lockmessage);
uiDefButS(block, MENU, B_PART_DISTR, "Distribution %t|Grid%x2|Random%x1|Jittered%x0", butx+butw/2,buty,butw/2,buth, &part->distr, 14.0, 0.0, 0, 0, "How to distribute particles on selected element");
if(part->distr==PART_DISTR_JIT) {
uiDefButF(block, NUM, B_PART_DISTR, "Amount:", butx,(buty-=buth),butw,buth, &part->jitfac, 0, 2.0, 1, 1, "Amount of jitter applied to the sampling");
@@ -4847,9 +5041,9 @@ static void object_panel_fluidsim(Object *ob)
char *msg = NULL;
block= uiNewBlock(&curarea->uiblocks, "object_fluidsim", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Fluid Simulation", "Physics", 1060, 0, 318, 204)==0) return;
+ if(uiNewPanel(curarea, block, "Fluid", "Physics", 1060, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
if(ob->type==OB_MESH) {
if(((Mesh *)ob->data)->totvert == 0) {
@@ -5143,10 +5337,10 @@ static void object_panel_fluidsim(Object *ob)
return;
} else {
- msg = "Object not enabled for fluid simulation...";
+ msg = "Object not enabled for fluid simulation.";
}
} else {
- msg = "Only Mesh Objects can participate.";
+ msg = "Only mesh objects can do fluid simulation.";
}
errMessage:
yline -= lineHeight + 5;
@@ -5183,7 +5377,7 @@ static void object_cloth__enabletoggle(void *ob_v, void *arg2)
BIF_undo_push("Del modifier");
- ob->softflag |= OB_SB_RESET;
+ //ob->softflag |= OB_SB_RESET;
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWIMAGE, 0);
@@ -5266,10 +5460,15 @@ static void object_panel_cloth(Object *ob)
uiBut *but=NULL;
static int val, val2;
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ PointCache *cache;
+ ModifierData *md;
+ int libdata = 0;
block= uiNewBlock(&curarea->uiblocks, "object_cloth", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Cloth ", "Physics", 640, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
+ libdata= object_is_libdata(ob);
+ uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
val = (clmd ? 1:0);
@@ -5281,6 +5480,14 @@ static void object_panel_cloth(Object *ob)
{
but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Cloth", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become cloth");
uiButSetFunc(but, object_cloth__enabletoggle, ob, NULL);
+
+ md = (ModifierData*)clmd;
+ if(md) {
+ uiBlockBeginAlign(block);
+ uiDefIconButBitI(block, TOG, eModifierMode_Render, B_BAKE_CACHE_CHANGE, ICON_SCENE, 145, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable cloth during rendering");
+ but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_BAKE_CACHE_CHANGE, VICON_VIEW3D, 165, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable cloth during interactive display");
+ uiBlockEndAlign(block);
+ }
}
uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
@@ -5292,45 +5499,50 @@ static void object_panel_cloth(Object *ob)
char clmvg [] = "Vertex Groups%t|";
val2=0;
+ cache= clmd->point_cache;
/* GENERAL STUFF */
- uiClearButLock();
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
- else if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
+ if(!libdata) {
+ uiClearButLock();
+ if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
+ uiSetButLock(1, "Please leave editmode.");
+ else if(cache->flag & PTCACHE_BAKED)
+ uiSetButLock(1, "Simulation frames are baked");
+ }
uiDefBut(block, LABEL, 0, "Material Preset:", 10,170,150,20, NULL, 0.0, 0, 0, 0, "");
- but=uiDefButS(block, MENU, B_CLOTH_RENEW, "Silk %x1|Cotton %x2|Rubber %x3|Denim %x4|Leather %x5|Custom %x0",
+ but=uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, "Silk %x1|Cotton %x2|Rubber %x3|Denim %x4|Leather %x5|Custom %x0",
160,170,150,20, &clmd->sim_parms->presets, 0, 0, 0, 0, "");
uiButSetFunc(but, cloth_presets_material, ob, NULL);
uiBlockBeginAlign(block);
- but = uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,150,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
+ but = uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "StructStiff:", 10,150,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
- but = uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,150,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)");
+ but = uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "BendStiff:", 160,150,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)");
uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
- but = uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 10,130,150,20, &clmd->sim_parms->Cdis, 0.0, 50.0, 100, 0, "Damping of cloth velocity (higher = more smooth, less jiggling)");
+ but = uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Spring Damp:", 10,130,150,20, &clmd->sim_parms->Cdis, 0.0, 50.0, 100, 0, "Damping of cloth velocity (higher = more smooth, less jiggling)");
uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
- uiDefButF(block, NUM, B_CLOTH_RENEW, "Air Damp:", 160,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Air Damp:", 160,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down");
- uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,110,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)");
+ uiDefButI(block, NUM, B_BAKE_CACHE_CHANGE, "Quality:", 10,110,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)");
- uiDefButF(block, NUM, B_CLOTH_RENEW, "Mass:", 160,110,150,20, &clmd->sim_parms->mass, 0.0, 10.0, 1000, 0, "Mass of cloth material.");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Mass:", 160,110,150,20, &clmd->sim_parms->mass, 0.0, 10.0, 1000, 0, "Mass of cloth material.");
uiDefBut(block, LABEL, 0, "Gravity:", 10,90,60,20, NULL, 0.0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,90,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
- uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,90,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
- uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,90,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "X:", 70,90,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Y:", 150,90,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Z:", 230,90,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
uiBlockEndAlign(block);
/* GOAL STUFF */
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, B_CLOTH_RENEW, "Pinning of cloth", 10,60,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
+ uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, B_BAKE_CACHE_CHANGE, "Pinning of cloth", 10,60,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (BLI_countlist (&ob->defbase) > 0))
{
@@ -5359,18 +5571,18 @@ static void object_panel_cloth(Object *ob)
sprintf (clvg2, "%s%s", clmvg, clvg1);
- uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,60,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
+ uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, clvg2, 160,60,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
MEM_freeN (clvg1);
MEM_freeN (clvg2);
}
- uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,40,150,20, &clmd->sim_parms->goalspring, 0.0, 50.0, 50, 0, "Pin (vertex target position) spring stiffness");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Pin Stiff:", 10,40,150,20, &clmd->sim_parms->goalspring, 0.0, 50.0, 50, 0, "Pin (vertex target position) spring stiffness");
uiDefBut(block, LABEL, 0, "",160,40,150,20, NULL, 0.0, 0, 0, 0, "");
- // uiDefButI(block, NUM, B_CLOTH_RENEW, "Pin Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 1.0, 100.0, 10, 0, "Pined damping (higher = doesn't oszilate so much)");
+ // uiDefButI(block, NUM, B_BAKE_CACHE_CHANGE, "Pin Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 1.0, 100.0, 10, 0, "Pined damping (higher = doesn't oszilate so much)");
/*
// nobody is changing these ones anyway
- uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
- uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Min:", 10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Max:", 160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
*/
}
else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
@@ -5400,78 +5612,42 @@ static void object_panel_cloth(Object *ob)
uiBlockEndAlign(block);
}
-static void object_cloth__protecttoggle(void *ob_v, void *arg2)
-{
- Object *ob = ob_v;
- int cageIndex, stack_index;
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
-
- // automatically enable modifier in editmode when we havee a protected cache
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)
- {
- cageIndex = modifiers_getCageIndex(ob_v, NULL );
- stack_index = modifiers_indexInObject(ob_v, (ModifierData *)clmd);
- if( stack_index >= cageIndex )
- ((ModifierData *)clmd)->mode ^= eModifierMode_OnCage;
- }
- else
- {
- ((ModifierData *)clmd)->mode ^= eModifierMode_OnCage;
- }
-
-}
-
-
static void object_panel_cloth_II(Object *ob)
{
uiBlock *block;
- uiBut *but = NULL;
ClothModifierData *clmd = NULL;
+ PointCache *cache;
+ static PTCacheID staticpid;
+ int libdata;
block= uiNewBlock(&curarea->uiblocks, "object_cloth_II", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Cloth ", "Physics");
- if(uiNewPanel(curarea, block, "Cloth Cache/Collisions", "Physics", 651, 0, 318, 204)==0) return;
+ if(uiNewPanel(curarea, block, "Cloth Collision", "Physics", 651, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ libdata= object_is_libdata(ob);
+ uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
if(clmd)
- {
- uiClearButLock();
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
- else if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
-
- uiDefButI(block, NUM, B_CLOTH_RENEW, "First Frame:",10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts");
- uiDefButI(block, NUM, B_CLOTH_RENEW, "Last Frame:",160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops");
-
- uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, "");
-
- if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE))
- {
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)
- uiClearButLock();
- }
-
- if (!G.relbase_valid)
- {
- uiDefBut(block, LABEL, 0, "Cache deactivated until file is saved.", 10,120,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, " ", 10,100,300,40, NULL, 0.0, 0, 0, 0, "");
- }
- else
- {
- but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache & Enable Cache Editing", 10,120,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed. This also enabled the cache beeing edited in editmode.");
- uiButSetFunc(but, object_cloth__protecttoggle, ob, NULL);
- uiDefBut(block, LABEL, 0, "Clear cache:", 10,100,90,20, NULL, 0.0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 100, 100,100,20, NULL, 0.0, 0.0, 10, 0, "Free ALL cloth cache without preroll");
- uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 200, 100,110,20, NULL, 0.0, 0.0, 10, 0, "Free cloth cache starting from next frame");
- uiDefBut(block, LABEL, 0, " ", 10,80,300,20, NULL, 0.0, 0, 0, 0, "");
+ {
+ BKE_ptcache_id_from_cloth(&staticpid, ob, clmd);
+ cache= staticpid.cache;
+
+ if(!libdata) {
+ uiClearButLock();
+ if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
+ uiSetButLock(1, "Please leave editmode.");
}
-
- if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE))
- {
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)
- uiSetButLock(1, "Cache is protected");
+
+ object_physics_bake_buttons(block, &staticpid, 135, libdata);
+
+ uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, "");
+
+ if(!libdata) {
+ if(!(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE))
+ if(cache->flag & PTCACHE_BAKED)
+ uiSetButLock(1, "Simulation frames are baked");
}
/*
@@ -5482,19 +5658,19 @@ static void object_panel_cloth_II(Object *ob)
uiDefBut(block, LABEL, 0, " ", 10,80,145,20, NULL, 0.0, 0, 0, 0, "");
*/
#if WITH_BULLET == 1
- uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_ENABLED, B_CLOTH_RENEW, "Enable collisions", 10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object");
+ uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_ENABLED, B_BAKE_CACHE_CHANGE, "Enable collisions", 10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object");
if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
{
- uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame");
- uiDefButS(block, NUM, B_CLOTH_RENEW, "Collision Quality:", 10,40,150,20, &clmd->coll_parms->loop_count, 1.0, 20.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower)");
- uiDefButF(block, NUM, B_CLOTH_RENEW, "Friction:", 160,40,150,20, &clmd->coll_parms->friction, 0.0, 80.0, 1.0, 0, "Friction force if a collision happened (0=movement not changed, 100=no movement left)");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Collision Quality:", 10,40,150,20, &clmd->coll_parms->loop_count, 1.0, 20.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower)");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Friction:", 160,40,150,20, &clmd->coll_parms->friction, 0.0, 80.0, 1.0, 0, "Friction force if a collision happened (0=movement not changed, 100=no movement left)");
- uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_SELF, B_CLOTH_RENEW, "Enable selfcollisions", 10,20,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable selfcollisions with this object");
+ uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_SELF, B_BAKE_CACHE_CHANGE, "Enable selfcollisions", 10,20,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable selfcollisions with this object");
if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)
{
- uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 160,20,150,20, &clmd->coll_parms->selfepsilon, 0.5f, 1.0, 0.01f, 0, "0.5 means no distance at all, 1.0 is maximum distance");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Min Distance:", 160,20,150,20, &clmd->coll_parms->selfepsilon, 0.5f, 1.0, 0.01f, 0, "0.5 means no distance at all, 1.0 is maximum distance");
// self_loop_count
- uiDefButS(block, NUM, B_CLOTH_RENEW, "Selfcoll Quality:", 10,0,150,20, &clmd->coll_parms->self_loop_count, 1.0, 10.0, 1.0, 0, "How many selfcollision iterations should be done. (higher = better = slower), can be changed for each frame");
+ uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Selfcoll Quality:", 10,0,150,20, &clmd->coll_parms->self_loop_count, 1.0, 10.0, 1.0, 0, "How many selfcollision iterations should be done. (higher = better = slower), can be changed for each frame");
}
else
uiDefBut(block, LABEL, 0, "",160,20,150,20, NULL, 0.0, 0, 0, 0, "");
@@ -5514,12 +5690,15 @@ static void object_panel_cloth_III(Object *ob)
{
uiBlock *block;
ClothModifierData *clmd = NULL;
+ PointCache *cache;
+ int libdata;
block= uiNewBlock(&curarea->uiblocks, "object_cloth_III", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Cloth ", "Physics");
if(uiNewPanel(curarea, block, "Cloth Advanced", "Physics", 651, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ libdata= object_is_libdata(ob);
+ uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
@@ -5529,23 +5708,18 @@ static void object_panel_cloth_III(Object *ob)
char *clvg1, *clvg2;
char clmvg [] = "Vertex Groups%t|None%x0|";
char clmvg2 [] = "Vertex Groups%t|None%x0|";
+
+ cache= clmd->point_cache;
- uiClearButLock();
- if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
- else if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
-
- uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT, REDRAWBUTSOBJECT, "Autoprotect cache",10,160,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Enables automatic toggling of the 'Protect cache' button from the 2nd panel.");
-
- if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT)
- {
- uiDefButI(block, NUM, B_DIFF, "From frame:",160,160,150,20, &clmd->sim_parms->autoprotect, 0.0, MAXFRAME + 1, 1, 0, "Frame on which the 'Protect Cache' button (2nd panel) is toggled automatically (To prevent accidently cleaning it).");
- }
- else
- {
- uiDefBut(block, LABEL, 0, " ", 160,160,150,20, NULL, 0.0, 0, 0, 0, "");
+ if(!libdata) {
+ uiClearButLock();
+ if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
+ uiSetButLock(1, "Please leave editmode.");
+ else if(cache->flag & PTCACHE_BAKED)
+ uiSetButLock(1, "Simulation frames are baked");
}
-
- uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_SCALING, B_CLOTH_RENEW, "Enable stiffness scaling",10,130,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "If enabled, stiffness can be scaled along a weight painted vertex group.");
+
+ uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_SCALING, B_BAKE_CACHE_CHANGE, "Enable stiffness scaling",10,130,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "If enabled, stiffness can be scaled along a weight painted vertex group.");
if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)&& (BLI_countlist (&ob->defbase) > 0))
{
@@ -5572,7 +5746,7 @@ static void object_panel_cloth_III(Object *ob)
sprintf (clvg2, "%s%s", clmvg, clvg1);
- uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 10,90,150,20, &clmd->sim_parms->vgroup_struct, 0, defCount, 0, 0, "Browses available vertex groups");
+ uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, clvg2, 10,90,150,20, &clmd->sim_parms->vgroup_struct, 0, defCount, 0, 0, "Browses available vertex groups");
MEM_freeN (clvg1);
MEM_freeN (clvg2);
@@ -5596,19 +5770,19 @@ static void object_panel_cloth_III(Object *ob)
sprintf (clvg2, "%s%s", clmvg2, clvg1);
- uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,90,150,20, &clmd->sim_parms->vgroup_bend, 0, defCount, 0, 0, "Browses available vertex groups");
+ uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, clvg2, 160,90,150,20, &clmd->sim_parms->vgroup_bend, 0, defCount, 0, 0, "Browses available vertex groups");
MEM_freeN (clvg1);
MEM_freeN (clvg2);
- uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 10000.0, 0.01f, 0, "Maximum structural stiffness value");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 10000.0, 0.01f, 0, "Maximum structural stiffness value");
- uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 10000.0, 0.01f, 0, "Maximum bending stiffness value");
+ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 10000.0, 0.01f, 0, "Maximum bending stiffness value");
}
else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)
{
uiDefBut(block, LABEL, 0, " ", 10,110,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "No vertex group for pinning available.", 10,90,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "No vertex group for stiffness scaling available.", 10,90,300,20, NULL, 0.0, 0, 0, 0, "");
}
@@ -5642,9 +5816,9 @@ void physics_panels()
/* check context here */
ob= OBACT;
if(ob) {
- if(ob->type==OB_MESH)
- object_panel_deflection(ob);
object_panel_fields(ob);
+ if(ob->type==OB_MESH)
+ object_panel_collision(ob);
object_softbodies(ob);
object_softbodies_collision(ob);
object_softbodies_solver(ob);
@@ -5666,7 +5840,8 @@ void particle_panels()
psys=psys_get_current(ob);
- if(psys){
+ if(psys ){
+ object_panel_particle_bake(ob);
object_panel_particle_physics(ob);
object_panel_particle_visual(ob);
object_panel_particle_simplification(ob);
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index b6b1f632041..faab326ee6b 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -3507,34 +3507,28 @@ static int cached_dynamics(int sfra, int efra)
{
Base *base = G.scene->base.first;
Object *ob;
- ModifierData *md;
ParticleSystem *psys;
- int i, stack_index=-1, cached=1;
+ int i, cached=1;
+ PTCacheID pid;
while(base && cached) {
ob = base->object;
if(ob->softflag & OB_SB_ENABLE && ob->soft) {
- for(i=0, md=ob->modifiers.first; md; i++, md=md->next) {
- if(md->type == eModifierType_Softbody) {
- stack_index = i;
- break;
- }
- }
+ BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
+
for(i=sfra; i<=efra && cached; i++)
- cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index);
+ cached &= BKE_ptcache_id_exist(&pid, i);
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,psys));
if(psys->part->type==PART_HAIR) {
- if(psys->softflag & OB_SB_ENABLE && psys->soft);
- else
- stack_index = -1;
- }
+ if(psys->softflag & OB_SB_ENABLE && psys->soft) {
+ BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
- if(stack_index >= 0)
- for(i=sfra; i<=efra && cached; i++)
- cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index);
+ for(i=sfra; i<=efra && cached; i++)
+ cached &= BKE_ptcache_id_exist(&pid, i);
+ }
+ }
}
base = base->next;
diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c
index 9190b3263f0..504c2ab107f 100644
--- a/source/blender/src/edit.c
+++ b/source/blender/src/edit.c
@@ -842,6 +842,11 @@ void countall()
G.totobj+=tot;
count_object(ob, base->flag & SELECT, tot);
}
+ else if((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
+ int tot= count_duplilist(ob);
+ G.totobj+=tot;
+ count_object(ob, base->flag & SELECT, tot);
+ }
else {
count_object(ob, base->flag & SELECT, 1);
G.totobj++;
@@ -1301,7 +1306,7 @@ void snap_sel_to_grid()
base= base->next;
}
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
allqueue(REDRAWVIEW3D, 0);
}
@@ -1414,7 +1419,7 @@ void snap_sel_to_curs()
base= base->next;
}
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
allqueue(REDRAWVIEW3D, 0);
}
@@ -1819,7 +1824,7 @@ void snap_to_center()
base= base->next;
}
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
allqueue(REDRAWVIEW3D, 0);
}
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index fb8a3e5f769..e5c92de5e98 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -349,18 +349,6 @@ void editipo_changed(SpaceIpo *si, int doredraw)
allqueue(REDRAWVIEW3D, 0);
}
else if(si->blocktype==ID_PA){
- Object *ob=OBACT;
- ParticleSystem *psys = ob->particlesystem.first;
-
- /* find out if we need to initialize particles */
- for(; psys; psys=psys->next) {
- if(psys->part->ipo==si->ipo) {
- ei= si->editipo;
- for(a=0; a<si->totipo; a++, ei++)
- if(ei->icu && ELEM3(ei->icu->adrcode,PART_EMIT_FREQ,PART_EMIT_LIFE,PART_EMIT_SIZE))
- psys_flush_settings(psys->part,PSYS_INIT,1);
- }
- }
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
}
@@ -3499,7 +3487,7 @@ void common_insertkey(void)
else if(event==13) BIF_undo_push("Insert VisualLocRot Key");
else if(event==15) BIF_undo_push("Insert Needed Key");
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
allspace(REMAKEIPO, 0);
allqueue(REDRAWIPO, 0);
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
index 2c1118bb588..765374f9967 100644
--- a/source/blender/src/editmesh.c
+++ b/source/blender/src/editmesh.c
@@ -77,6 +77,7 @@
#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_pointcache.h"
+#include "BKE_softbody.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -796,6 +797,78 @@ static void edge_drawflags(void)
}
}
+static int editmesh_pointcache_edit(Object *ob, int totvert, PTCacheID *pid_p, float mat[][4], int load)
+{
+ Cloth *cloth;
+ SoftBody *sb;
+ ClothModifierData *clmd;
+ PTCacheID pid, tmpid;
+ int cfra= (int)G.scene->r.cfra, found= 0;
+
+ pid.cache= NULL;
+
+ /* check for cloth */
+ if(modifiers_isClothEnabled(ob)) {
+ clmd= (ClothModifierData*)modifiers_findByType(ob, eModifierType_Cloth);
+ cloth= clmd->clothObject;
+
+ BKE_ptcache_id_from_cloth(&tmpid, ob, clmd);
+
+ /* verify vertex count and baked status */
+ if(cloth && (totvert == cloth->numverts)) {
+ if((tmpid.cache->flag & PTCACHE_BAKED) && (tmpid.cache->flag & PTCACHE_BAKE_EDIT)) {
+ pid= tmpid;
+
+ if(load && (pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE))
+ found= 1;
+ }
+ }
+ }
+
+ /* check for softbody */
+ if(!found && ob->soft) {
+ sb= ob->soft;
+
+ BKE_ptcache_id_from_softbody(&tmpid, ob, sb);
+
+ /* verify vertex count and baked status */
+ if(sb->bpoint && (totvert == sb->totpoint)) {
+ if((tmpid.cache->flag & PTCACHE_BAKED) && (tmpid.cache->flag & PTCACHE_BAKE_EDIT)) {
+ pid= tmpid;
+
+ if(load && (pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE))
+ found= 1;
+ }
+ }
+ }
+
+ /* if not making editmesh verify editing was active for this point cache */
+ if(load) {
+ if(found)
+ pid.cache->flag &= ~PTCACHE_BAKE_EDIT_ACTIVE;
+ else
+ return 0;
+ }
+
+ /* check if we have cache for this frame */
+ if(pid.cache && BKE_ptcache_id_exist(&pid, cfra)) {
+ *pid_p = pid;
+
+ if(load) {
+ Mat4CpyMat4(mat, ob->obmat);
+ }
+ else {
+ pid.cache->editframe= cfra;
+ pid.cache->flag |= PTCACHE_BAKE_EDIT_ACTIVE;
+ Mat4Invert(mat, ob->obmat); /* ob->imat is not up to date */
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
/* turns Mesh into editmesh */
void make_editMesh()
{
@@ -809,10 +882,11 @@ void make_editMesh()
EditFace *efa;
EditEdge *eed;
EditSelection *ese;
- int tot, a, eekadoodle= 0, cloth_enabled = 0;
- ClothModifierData *clmd = NULL;
- Cloth *cloth = NULL;
- float temp[3];
+ PTCacheID pid;
+ Cloth *cloth;
+ SoftBody *sb;
+ float cacheco[3], cachemat[4][4], *co;
+ int tot, a, cacheedit= 0, eekadoodle= 0;
#ifdef WITH_VERSE
if(me->vnode){
@@ -847,49 +921,29 @@ void make_editMesh()
/* make editverts */
CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
mvert= me->mvert;
-
- /* lots of checks to be sure if we have nice cloth object */
- if(modifiers_isClothEnabled(G.obedit))
- {
- clmd = (ClothModifierData *) modifiers_findByType(G.obedit, eModifierType_Cloth);
- cloth = clmd->clothObject;
-
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_EDITMODE;
-
- /* just to be sure also check vertcount */
- /* also check if we have a protected cache */
- if(cloth && (tot == cloth->numverts) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
- {
- /* check if we have cache for this frame */
- int stack_index = modifiers_indexInObject(G.obedit, (ModifierData *)clmd);
-
- if(BKE_ptcache_id_exist((ID *)G.obedit, G.scene->r.cfra, stack_index))
- {
- cloth_enabled = 1;
-
- clmd->sim_parms->editedframe = G.scene->r.cfra;
-
- /* inverse matrix is not uptodate... */
- Mat4Invert ( G.obedit->imat, G.obedit->obmat );
- if(G.rt > 0)
- printf("make_editmesh --> cloth_enabled\n");
- }
- }
- }
+
+ cacheedit= editmesh_pointcache_edit(G.obedit, tot, &pid, cachemat, 0);
evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
for(a=0; a<tot; a++, mvert++) {
- if(cloth_enabled)
- {
- VECCOPY(temp, cloth->verts[a].x);
- Mat4MulVecfl ( G.obedit->imat, temp );
- eve= addvertlist(temp, NULL);
-
- /* TODO: what about normals? */
+ if(cacheedit) {
+ if(pid.type == PTCACHE_TYPE_CLOTH) {
+ cloth= ((ClothModifierData*)pid.data)->clothObject;
+ VECCOPY(cacheco, cloth->verts[a].x)
+ }
+ else if(pid.type == PTCACHE_TYPE_SOFTBODY) {
+ sb= (SoftBody*)pid.data;
+ VECCOPY(cacheco, sb->bpoint[a].pos)
+ }
+
+ Mat4MulVecfl(cachemat, cacheco);
+ co= cacheco;
}
- else
- eve= addvertlist(mvert->co, NULL);
+ else
+ co= mvert->co;
+
+ eve= addvertlist(co, NULL);
evlist[a]= eve;
// face select sets selection in next loop
@@ -1008,9 +1062,12 @@ void make_editMesh()
EM_hide_reset();
/* sets helper flags which arent saved */
EM_fgon_flags();
+
+ /* vertex coordinates change with cache edit, need to recalc */
+ if(cacheedit)
+ recalc_editnormals();
countall();
-
}
/* makes Mesh out of editmesh */
@@ -1026,11 +1083,12 @@ void load_editMesh(void)
EditFace *efa, *efa_act;
EditEdge *eed;
EditSelection *ese;
- float *fp, *newkey, *oldkey, nor[3];
- int i, a, ototvert, totedge=0, cloth_enabled = 0;
- ClothModifierData *clmd = NULL;
- Cloth *cloth = NULL;
- float temp[3], dt = 0.0;
+ SoftBody *sb;
+ Cloth *cloth;
+ ClothModifierData *clmd;
+ PTCacheID pid;
+ float *fp, *newkey, *oldkey, nor[3], cacheco[3], cachemat[4][4];
+ int i, a, ototvert, totedge=0, cacheedit= 0;
#ifdef WITH_VERSE
if(em->vnode) {
@@ -1097,60 +1155,50 @@ void load_editMesh(void)
/* the vertices, use ->tmp.l as counter */
eve= em->verts.first;
a= 0;
-
- /* lots of checks to be sure if we have nice cloth object */
- if(modifiers_isClothEnabled(G.obedit))
- {
- clmd = (ClothModifierData *) modifiers_findByType(G.obedit, eModifierType_Cloth);
- cloth = clmd->clothObject;
-
- /* just to be sure also check vertcount */
- /* also check if we have a protected cache */
- if(cloth && (G.totvert == cloth->numverts) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
- {
- /* check if we have cache for this frame */
- int stack_index = modifiers_indexInObject(G.obedit, (ModifierData *)clmd);
-
- if(BKE_ptcache_id_exist((ID *)G.obedit, clmd->sim_parms->editedframe, stack_index))
- {
- cloth_enabled = 1;
-
- /* inverse matrix is not uptodate... */
- Mat4Invert ( G.obedit->imat, G.obedit->obmat );
- dt = 1.0f / clmd->sim_parms->stepsPerFrame;
- }
- if(G.rt > 0)
- printf("loadmesh --> tot: %d, num: %d\n", G.totvert, cloth->numverts);
- }
- }
-
- i=0;
+
+ /* check for point cache editing */
+ cacheedit= editmesh_pointcache_edit(G.obedit, G.totvert, &pid, cachemat, 1);
+
while(eve) {
-
- if(cloth_enabled)
- {
- if(G.rt > 0)
- printf("loadmesh --> cloth_enabled\n");
-
- VECCOPY(temp, cloth->verts[i].x);
- VECCOPY(cloth->verts[i].x, eve->co);
- Mat4MulVecfl ( G.obedit->obmat, cloth->verts[i].x );
-
-
- // not physical correct but gives nicer results when commented
- VECSUB(temp, cloth->verts[i].x, temp);
- VecMulf(temp, 1.0f / (dt*10.0));
- VECADD(cloth->verts[i].v, cloth->verts[i].v, temp);
-
- if(oldverts) {
- VECCOPY(mvert->co, oldverts[i].co);
- if(G.rt > 0)
- printf("loadmesh --> cloth_enabled oldverts\n");
+ if(cacheedit) {
+ if(pid.type == PTCACHE_TYPE_CLOTH) {
+ clmd= (ClothModifierData*)pid.data;
+ cloth= clmd->clothObject;
+
+ /* assign position */
+ VECCOPY(cacheco, cloth->verts[a].x)
+ VECCOPY(cloth->verts[a].x, eve->co);
+ Mat4MulVecfl(cachemat, cloth->verts[a].x);
+
+ /* find plausible velocity, not physical correct but gives
+ * nicer results when commented */
+ VECSUB(cacheco, cloth->verts[a].x, cacheco);
+ VecMulf(cacheco, clmd->sim_parms->stepsPerFrame*10.0f);
+ VECADD(cloth->verts[a].v, cloth->verts[a].v, cacheco);
+ }
+ else if(pid.type == PTCACHE_TYPE_SOFTBODY) {
+ sb= (SoftBody*)pid.data;
+
+ /* assign position */
+ VECCOPY(cacheco, sb->bpoint[a].pos)
+ VECCOPY(sb->bpoint[a].pos, eve->co);
+ Mat4MulVecfl(cachemat, sb->bpoint[a].pos);
+
+ /* changing velocity for softbody doesn't seem to give
+ * good results? */
+#if 0
+ VECSUB(cacheco, sb->bpoint[a].pos, cacheco);
+ VecMulf(cacheco, sb->minloops*10.0f);
+ VECADD(sb->bpoint[a].vec, sb->bpoint[a].pos, cacheco);
+#endif
}
- i++;
+
+ if(oldverts)
+ VECCOPY(mvert->co, oldverts[a].co)
}
- else
+ else
VECCOPY(mvert->co, eve->co);
+
mvert->mat_nr= 255; /* what was this for, halos? */
/* vertex normal */
@@ -1180,34 +1228,12 @@ void load_editMesh(void)
mvert++;
}
- /* burn changes to cache */
- if(cloth_enabled)
- {
- if(G.rt > 0)
- printf("loadmesh --> cloth_enabled cloth_write_cache\n");
- cloth_write_cache(G.obedit, clmd, clmd->sim_parms->editedframe);
-
- if(G.scene->r.cfra != clmd->sim_parms->editedframe)
- {
- if(cloth_read_cache(G.obedit, clmd, G.scene->r.cfra))
- implicit_set_positions(clmd);
- }
- else
- implicit_set_positions(clmd);
-
- clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
- }
- else
- {
- if(modifiers_isClothEnabled(G.obedit)) {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(G.obedit, eModifierType_Cloth);
- if(G.rt > 0)
- printf("loadmesh --> CLOTH_SIMSETTINGS_FLAG_RESET\n");
- /* only reset cloth when no cache was used */
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
- clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
- }
+ /* write changes to cache */
+ if(cacheedit) {
+ if(pid.type == PTCACHE_TYPE_CLOTH)
+ cloth_write_cache(G.obedit, pid.data, pid.cache->editframe);
+ else if(pid.type == PTCACHE_TYPE_SOFTBODY)
+ sbWriteCache(G.obedit, pid.cache->editframe);
}
/* the edges */
@@ -1469,12 +1495,9 @@ void load_editMesh(void)
/* remake softbody of all users */
if(me->id.us>1) {
Base *base;
- for(base= G.scene->base.first; base; base= base->next) {
- if(base->object->data==me) {
- base->object->softflag |= OB_SB_REDO;
+ for(base= G.scene->base.first; base; base= base->next)
+ if(base->object->data==me)
base->object->recalc |= OB_RECALC_DATA;
- }
- }
}
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c
index 0fc8baae154..6d9adda85d0 100644
--- a/source/blender/src/editnla.c
+++ b/source/blender/src/editnla.c
@@ -2052,6 +2052,6 @@ void copy_action_modifiers(void)
BIF_undo_push("Copy Action Modifiers");
allqueue(REDRAWNLA, 0);
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
}
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 07973926503..34b69bc1e64 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -339,6 +339,7 @@ void delete_obj(int ok)
allqueue(REDRAWNLA, 0);
DAG_scene_sort(G.scene);
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
BIF_undo_push("Delete object(s)");
}
@@ -964,7 +965,7 @@ void clear_parent(void)
}
DAG_scene_sort(G.scene);
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWOOPS, 0);
@@ -1125,7 +1126,7 @@ void clear_object(char mode)
allqueue(REDRAWVIEW3D, 0);
if(armature_clear==0) /* in this case flush was done */
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
BIF_undo_push(str);
}
@@ -1625,7 +1626,7 @@ void make_parent(void)
allqueue(REDRAWOOPS, 0);
DAG_scene_sort(G.scene);
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
BIF_undo_push("make Parent");
}
@@ -1787,20 +1788,6 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b
/* for example; displist make is different in editmode */
if(freedata) G.obedit= NULL;
- /* total remake of softbody data */
- if(modifiers_isSoftbodyEnabled(ob)) {
- if (ob->soft && ob->soft->keys) {
- notice("Erase Baked SoftBody");
- }
-
- sbObjectToSoftbody(ob);
- }
-
- if(modifiers_isClothEnabled(ob)) {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- }
-
if(ob->type==OB_MESH && get_mesh(ob)->mr)
multires_edge_level_update(ob, get_mesh(ob));
@@ -2106,7 +2093,7 @@ void docenter(int centermode)
base= base->next;
}
if (tot_change) {
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
allqueue(REDRAWVIEW3D, 0);
BIF_undo_push("Do Center");
}
@@ -3148,7 +3135,7 @@ void flip_subdivison(int level)
allqueue(REDRAWOOPS, 0);
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWBUTSOBJECT, 0);
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
if(particles)
BIF_undo_push("Switch particles on/off");
@@ -3657,7 +3644,7 @@ void copy_attr(short event)
if(do_scene_sort)
DAG_scene_sort(G.scene);
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
if(event==20) {
allqueue(REDRAWBUTSOBJECT, 0);
@@ -3904,7 +3891,7 @@ void make_links(short event)
allqueue(REDRAWOOPS, 0);
allqueue(REDRAWBUTSHEAD, 0);
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
BIF_undo_push("Create links");
}
@@ -5292,7 +5279,7 @@ void adduplicate(int mode, int dupflag)
copy_object_set_idnew(dupflag);
DAG_scene_sort(G.scene);
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
countall();
if(mode==0) {
diff --git a/source/blender/src/editparticle.c b/source/blender/src/editparticle.c
index 6543b3fa017..af323c9df9c 100644
--- a/source/blender/src/editparticle.c
+++ b/source/blender/src/editparticle.c
@@ -1126,9 +1126,6 @@ void PE_set_particle_edit(void)
}
else{
G.f &= ~G_PARTICLEEDIT;
-
- if(psys->soft)
- psys->softflag |= OB_SB_REDO;
}
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c
index ac90d3ed119..43d692a99c9 100644
--- a/source/blender/src/fluidsim.c
+++ b/source/blender/src/fluidsim.c
@@ -1129,6 +1129,11 @@ void fluidsimBake(struct Object *ob)
}
}
+void fluidsimFreeBake(struct Object *ob)
+{
+ /* not implemented yet */
+}
+
#else /* DISABLE_ELBEEM */
@@ -1149,5 +1154,8 @@ FluidsimSettings* fluidsimSettingsCopy(FluidsimSettings *fss) {
void fluidsimBake(struct Object *ob) {
}
+void fluidsimFreeBake(struct Object *ob) {
+}
+
#endif /* DISABLE_ELBEEM */
diff --git a/source/blender/src/header_time.c b/source/blender/src/header_time.c
index 7b98d2f5f4c..748dcac9233 100644
--- a/source/blender/src/header_time.c
+++ b/source/blender/src/header_time.c
@@ -56,6 +56,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_pointcache.h"
#include "BSE_drawipo.h"
#include "BSE_drawview.h"
@@ -69,6 +70,24 @@
#include "butspace.h"
#include "mydevice.h"
+static void start_animated_screen(SpaceTime *stime)
+{
+ add_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM, stime->redraws);
+
+ if(stime->redraws & TIME_WITH_SEQ_AUDIO)
+ audiostream_start( CFRA );
+
+ BKE_ptcache_set_continue_physics((stime->redraws & TIME_CONTINUE_PHYSICS));
+}
+
+static void end_animated_screen(SpaceTime *stime)
+{
+ rem_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
+
+ audiostream_stop();
+ BKE_ptcache_set_continue_physics(0);
+}
+
void do_time_buttons(ScrArea *sa, unsigned short event)
{
SpaceTime *stime= sa->spacedata.first;
@@ -80,17 +99,11 @@ void do_time_buttons(ScrArea *sa, unsigned short event)
update_for_newframe();
break;
case B_TL_PLAY:
- add_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM, stime->redraws);
- if(stime->redraws & TIME_WITH_SEQ_AUDIO)
- audiostream_start( CFRA );
-
+ start_animated_screen(stime);
break;
case B_TL_STOP:
- rem_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
- if(stime->redraws & TIME_WITH_SEQ_AUDIO)
- audiostream_stop();
+ end_animated_screen(stime);
allqueue(REDRAWALL, 0);
-
break;
case B_TL_FF:
/* end frame */
@@ -132,7 +145,7 @@ static void do_time_redrawmenu(void *arg, int event)
stime->redraws ^= event;
/* update handler when it's running */
if(has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM))
- add_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM, stime->redraws);
+ start_animated_screen(stime);
}
else {
if(event==1001) {
@@ -182,6 +195,12 @@ static uiBlock *time_redrawmenu(void *arg_unused)
sprintf(str, "Set Frames/Sec (%d/%f)", G.scene->r.frs_sec, G.scene->r.frs_sec_base);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, str, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1001, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ if(stime->redraws & TIME_CONTINUE_PHYSICS) icon= ICON_CHECKBOX_HLT;
+ else icon= ICON_CHECKBOX_DEHLT;
+ uiDefIconTextBut(block, BUTM, 1, icon, "Continue Physics", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, TIME_CONTINUE_PHYSICS, "During playblack, continue physics simulations regardless of the frame number");
if(curarea->headertype==HEADERTOP) {
@@ -204,7 +223,8 @@ static void do_time_viewmenu(void *arg, int event)
switch(event) {
case 2: /* Play Back Animation */
- add_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM, stime->redraws);
+ if(!has_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM))
+ start_animated_screen(stime);
break;
case 3: /* View All */
first= G.scene->r.sfra;
diff --git a/source/blender/src/interface_panel.c b/source/blender/src/interface_panel.c
index de1e70caeec..05a84ed301e 100644
--- a/source/blender/src/interface_panel.c
+++ b/source/blender/src/interface_panel.c
@@ -876,8 +876,8 @@ static void ui_draw_panel_header(uiBlock *block)
Panel *pa, *panel= block->panel;
float width;
int a, nr= 1, pnl_icons;
- char *panelname= panel->drawname[0]?panel->drawname:panel->panelname;
- char *str;
+ char *activename= panel->drawname[0]?panel->drawname:panel->panelname;
+ char *panelname, *str;
/* count */
pa= curarea->panels.first;
@@ -901,7 +901,7 @@ static void ui_draw_panel_header(uiBlock *block)
/* draw text label */
BIF_ThemeColor(TH_TEXT_HI);
ui_rasterpos_safe(4.0f+block->minx+pnl_icons, block->maxy+5.0f, block->aspect);
- BIF_DrawString(block->curfont, panelname, (U.transopts & USER_TR_BUTTONS));
+ BIF_DrawString(block->curfont, activename, (U.transopts & USER_TR_BUTTONS));
return;
}
@@ -915,6 +915,8 @@ static void ui_draw_panel_header(uiBlock *block)
pa= curarea->panels.first;
while(pa) {
panelname= pa->drawname[0]?pa->drawname:pa->panelname;
+ if(a == 0)
+ activename= panelname;
if(pa->active==0);
else if(pa==panel) {
@@ -928,7 +930,10 @@ static void ui_draw_panel_header(uiBlock *block)
/* draw the active text label */
BIF_ThemeColor(TH_TEXT);
ui_rasterpos_safe(16+pnl_icons+a*width, panel->sizey+4, block->aspect);
- str= ui_block_cut_str(block, panelname, (short)(width-10));
+ if(panelname != activename && strstr(panelname, activename) == panelname)
+ str= ui_block_cut_str(block, panelname+strlen(activename), (short)(width-10));
+ else
+ str= ui_block_cut_str(block, panelname, (short)(width-10));
BIF_DrawString(block->curfont, str, (U.transopts & USER_TR_BUTTONS));
a++;
@@ -942,7 +947,10 @@ static void ui_draw_panel_header(uiBlock *block)
/* draw an inactive tab label */
BIF_ThemeColorShade(TH_TEXT_HI, -40);
ui_rasterpos_safe(16+pnl_icons+a*width, panel->sizey+4, block->aspect);
- str= ui_block_cut_str(block, panelname, (short)(width-10));
+ if(panelname != activename && strstr(panelname, activename) == panelname)
+ str= ui_block_cut_str(block, panelname+strlen(activename), (short)(width-10));
+ else
+ str= ui_block_cut_str(block, panelname, (short)(width-10));
BIF_DrawString(block->curfont, str, (U.transopts & USER_TR_BUTTONS));
a++;
diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c
index 14b3286c03b..769e83d7a2d 100644
--- a/source/blender/src/poselib.c
+++ b/source/blender/src/poselib.c
@@ -1144,7 +1144,6 @@ static void poselib_preview_init_data (tPoseLib_PreviewData *pld, Object *ob, sh
/* After previewing poses */
static void poselib_preview_cleanup (tPoseLib_PreviewData *pld)
{
- Base *base;
Object *ob= pld->ob;
bPose *pose= pld->pose;
bArmature *arm= pld->arm;
@@ -1161,17 +1160,8 @@ static void poselib_preview_cleanup (tPoseLib_PreviewData *pld)
/* old optimize trick... this enforces to bypass the depgraph
* - note: code copied from transform_generics.c -> recalcData()
*/
- if ((arm->flag & ARM_DELAYDEFORM)==0) {
+ if ((arm->flag & ARM_DELAYDEFORM)==0)
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */
-
- /* bah, softbody exception... recalcdata doesnt reset */
- for (base= FIRSTBASE; base; base= base->next) {
- if (base->object->recalc & OB_RECALC_DATA)
- if (modifiers_isSoftbodyEnabled(base->object)) {
- base->object->softflag |= OB_SB_REDO;
- }
- }
- }
else
where_is_pose(ob);
@@ -1222,7 +1212,6 @@ static void poselib_preview_cleanup (tPoseLib_PreviewData *pld)
void poselib_preview_poses (Object *ob, short apply_active)
{
tPoseLib_PreviewData pld;
- Base *base;
unsigned short event;
short val=0;
@@ -1252,17 +1241,8 @@ void poselib_preview_poses (Object *ob, short apply_active)
/* old optimize trick... this enforces to bypass the depgraph
* - note: code copied from transform_generics.c -> recalcData()
*/
- if ((pld.arm->flag & ARM_DELAYDEFORM)==0) {
+ if ((pld.arm->flag & ARM_DELAYDEFORM)==0)
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */
-
- /* bah, softbody exception... recalcdata doesnt reset */
- for (base= FIRSTBASE; base; base= base->next) {
- if (base->object->recalc & OB_RECALC_DATA)
- if (modifiers_isSoftbodyEnabled(base->object)) {
- base->object->softflag |= OB_SB_REDO;
- }
- }
- }
else
where_is_pose(ob);
}
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index ab6c2b0533a..94781693b68 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -88,6 +88,7 @@
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_node.h"
+#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "BKE_sculpt.h"
#include "BKE_texture.h"
@@ -1841,12 +1842,26 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
view3d_border_zoom();
}
else if(G.qual==LR_CTRLKEY) {
- if(okee("Bake all selected")) {
- extern void softbody_bake(Object *ob);
- extern void fluidsimBake(Object *ob);
- softbody_bake(NULL);
- /* also bake first domain of selected objects... */
- fluidsimBake(NULL);
+ extern void pointcache_bake(PTCacheID *pid, int startframe);
+ extern void pointcache_free(PTCacheID *pid, int cacheonly);
+ extern void fluidsimBake(Object *ob);
+ extern void fluidsimFreeBake(Object *ob);
+ int pupval;
+
+ pupval= pupmenu("Physics Baking%t|Bake selected %x1|Free bake selected %x2|Free cache selected %x3");
+
+ if(pupval > 0) {
+ if(pupval == 1) {
+ pointcache_bake(NULL, 0);
+ /* also bake first domain of selected objects... */
+ fluidsimBake(NULL);
+ }
+ else if(pupval == 2) {
+ pointcache_free(NULL, 0);
+ fluidsimFreeBake(NULL);
+ }
+ else if(pupval == 3)
+ pointcache_free(NULL, 1);
}
}
else if(G.qual== (LR_ALTKEY|LR_CTRLKEY))
diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c
index 230e8b69de9..c8f8b158c3b 100644
--- a/source/blender/src/toets.c
+++ b/source/blender/src/toets.c
@@ -66,6 +66,8 @@
#include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
+#include "BKE_object.h"
+#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "BKE_utildefines.h"
@@ -76,7 +78,6 @@
#include "BIF_imasel.h"
#include "BIF_editparticle.h"
#include "BIF_interface.h"
-#include "BKE_object.h"
#include "BIF_poseobject.h"
#include "BIF_previewrender.h"
#include "BIF_renderwin.h"
@@ -701,6 +702,7 @@ int blenderqread(unsigned short event, short val)
/* stop playback on ESC always */
rem_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
audiostream_stop();
+ BKE_ptcache_set_continue_physics(0);
allqueue(REDRAWALL, 0);
break;
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index c153516705d..d92be2ec174 100644
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -79,12 +79,13 @@
#include "BIF_editaction.h"
#include "BKE_action.h" /* get_action_frame */
+#include "BKE_bad_level_calls.h"/* popmenu and error */
+#include "BKE_bmesh.h"
#include "BKE_constraint.h"
#include "BKE_global.h"
-#include "BKE_utildefines.h"
-#include "BKE_bad_level_calls.h"/* popmenu and error */
#include "BKE_particle.h"
-#include "BKE_bmesh.h"
+#include "BKE_pointcache.h"
+#include "BKE_utildefines.h"
#include "BSE_drawipo.h"
#include "BSE_editnla_types.h" /* for NLAWIDTH */
@@ -1134,6 +1135,11 @@ void Transform()
event= extern_qread(&val);
transformEvent(event, val);
}
+
+ if(BKE_ptcache_get_continue_physics()) {
+ do_screenhandlers(G.curscreen);
+ Trans.redraw= 1;
+ }
}
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 8d64aa16d7a..7efcdb93cbc 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -95,6 +95,7 @@
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_softbody.h"
#include "BKE_utildefines.h"
#include "BKE_bmesh.h"
@@ -3104,8 +3105,9 @@ static void set_trans_object_base_flags(TransInfo *t)
ob->recalc |= OB_RECALC_OB;
}
}
+
/* all recalc flags get flushed to all layers, so a layer flip later on works fine */
- DAG_scene_flush_update(G.scene, -1);
+ DAG_scene_flush_update(G.scene, -1, 0);
/* and we store them temporal in base (only used for transform code) */
/* this because after doing updates, the object->recalc is cleared */
@@ -3419,7 +3421,7 @@ static void recalc_all_ipos(void)
}
}
-/* inserting keys, refresh ipo-keys, softbody, redraw events... (ton) */
+/* inserting keys, refresh ipo-keys, pointcache, redraw events... (ton) */
/* note: transdata has been freed already! */
void special_aftertrans_update(TransInfo *t)
{
@@ -3569,16 +3571,13 @@ void special_aftertrans_update(TransInfo *t)
ob= base->object;
- if (modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_REDO;
- else if((ob == OBACT) && modifiers_isClothEnabled(ob)) {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- if(clmd)
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- }
-
- /* Set autokey if necessary */
- if ((!cancelled) && (t->mode != TFM_DUMMY) && (base->flag & SELECT)) {
- autokeyframe_ob_cb_func(ob, t->mode);
+ if(base->flag & SELECT && (t->mode != TFM_DUMMY)) {
+ if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH))
+ ob->recalc |= OB_RECALC_DATA;
+
+ /* Set autokey if necessary */
+ if (!cancelled)
+ autokeyframe_ob_cb_func(ob, t->mode);
}
base= base->next;
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index f5fc3ce517b..1e28b3076ba 100644
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -308,7 +308,7 @@ void recalcData(TransInfo *t)
base->object->ctime= -1234567.0f; // eveil!
}
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
}
}
else if (t->spacetype == SPACE_IPO) {
@@ -370,7 +370,7 @@ void recalcData(TransInfo *t)
}
base= base->next;
}
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
}
}
}
@@ -475,21 +475,6 @@ void recalcData(TransInfo *t)
/* old optimize trick... this enforces to bypass the depgraph */
if (!(arm->flag & ARM_DELAYDEFORM)) {
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */
-
- /* bah, softbody exception... recalcdata doesnt reset */
- for(base= FIRSTBASE; base; base= base->next) {
- if(base->object->recalc & OB_RECALC_DATA)
- {
- if(modifiers_isSoftbodyEnabled(base->object)) {
- base->object->softflag |= OB_SB_REDO;
- }
- else if(modifiers_isClothEnabled(base->object)) {
- ClothModifierData *clmd = (ClothModifierData *) modifiers_findByType(base->object, eModifierType_Cloth);
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- }
-
- }
- }
}
else
where_is_pose(ob);
@@ -501,12 +486,12 @@ void recalcData(TransInfo *t)
for(base= FIRSTBASE; base; base= base->next) {
Object *ob= base->object;
- /* this flag is from depgraph, was stored in nitialize phase, handled in drawview.c */
+ /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */
if(base->flag & BA_HAS_RECALC_OB)
ob->recalc |= OB_RECALC_OB;
if(base->flag & BA_HAS_RECALC_DATA)
ob->recalc |= OB_RECALC_DATA;
-
+
/* thanks to ob->ctime usage, ipos are not called in where_is_object,
unless we edit ipokeys */
if(base->flag & BA_DO_IPO) {
@@ -523,18 +508,6 @@ void recalcData(TransInfo *t)
}
}
- /* softbody & cloth exception */
- if(ob->recalc & OB_RECALC_DATA)
- {
- if(modifiers_isSoftbodyEnabled(ob)) {
- ob->softflag |= OB_SB_REDO;
- }
- else if(modifiers_isClothEnabled(ob)) {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- }
- }
-
/* proxy exception */
if(ob->proxy)
ob->proxy->recalc |= ob->recalc;
@@ -557,7 +530,6 @@ void recalcData(TransInfo *t)
/* update shaded drawmode while transform */
if(t->spacetype==SPACE_VIEW3D && G.vd->drawtype == OB_SHADED)
reshadeall_displist();
-
}
void initTransModeFlags(TransInfo *t, int mode)
diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c
index 63ab0616162..95ddade3de9 100644
--- a/source/blender/src/vpaint.c
+++ b/source/blender/src/vpaint.c
@@ -1347,23 +1347,6 @@ void weight_paint(void)
copy_wpaint_prev(&Gwp, NULL, 0);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- /* this flag is event for softbody to refresh weightpaint values */
- if(ob->soft) ob->softflag |= OB_SB_REDO;
-
- /* same goes for cloth */
- if(modifiers_isClothEnabled(ob)) {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- if(clmd)
- {
- /* check if we use the edited vertex group at all */
- if((clmd->sim_parms->vgroup_mass==ob->actdef) ||
- (clmd->sim_parms->vgroup_struct==ob->actdef)||
- (clmd->sim_parms->vgroup_bend==ob->actdef))
- {
- clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
- }
- }
- }
/* and particles too */
if(ob->particlesystem.first) {