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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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) {