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:
authorLukas Tönne <lukas.toenne@gmail.com>2016-12-28 19:30:58 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2016-12-28 19:30:58 +0300
commit6ecab6dd8e48d564a2b43e0e81e79d079e8b4c77 (patch)
tree618e2d24eb34a05a81f726dd52eb2b7468e9296d /source/blender/blenloader
parent605263177b8eea24c1449e4dbf0138175ec3dddf (diff)
Revert particle system and point cache removal in blender2.8 branch.
This reverts commit 5aa19be91263a249ffae75573e3b32f24269d890 and b4a721af694817fa921b119df83d33ede7d7fed0. Due to postponement of particle system rewrite it was decided to put particle code back into the 2.8 branch for the time being.
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r--source/blender/blenloader/intern/readfile.c465
-rw-r--r--source/blender/blenloader/intern/versioning_250.c77
-rw-r--r--source/blender/blenloader/intern/versioning_260.c36
-rw-r--r--source/blender/blenloader/intern/versioning_270.c100
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c7
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c208
-rw-r--r--source/blender/blenloader/intern/writefile.c226
7 files changed, 1113 insertions, 6 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 69fc85b63af..d3576a12b9c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -81,9 +81,9 @@
#include "DNA_nla_types.h"
#include "DNA_node_types.h"
#include "DNA_object_fluidsim.h" // NT
-#include "DNA_object_force.h"
#include "DNA_object_types.h"
#include "DNA_packedFile_types.h"
+#include "DNA_particle_types.h"
#include "DNA_property_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_text_types.h"
@@ -137,6 +137,8 @@
#include "BKE_node.h" // for tree type defines
#include "BKE_object.h"
#include "BKE_paint.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_report.h"
#include "BKE_sca.h" // for init_actuator
#include "BKE_scene.h"
@@ -3983,6 +3985,83 @@ static void direct_link_material(FileData *fd, Material *ma)
}
/* ************ READ PARTICLE SETTINGS ***************** */
+/* update this also to writefile.c */
+static const char *ptcache_data_struct[] = {
+ "", // BPHYS_DATA_INDEX
+ "", // BPHYS_DATA_LOCATION
+ "", // BPHYS_DATA_VELOCITY
+ "", // BPHYS_DATA_ROTATION
+ "", // BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
+ "", // BPHYS_DATA_SIZE:
+ "", // BPHYS_DATA_TIMES:
+ "BoidData" // case BPHYS_DATA_BOIDS:
+};
+
+static void direct_link_pointcache_cb(FileData *fd, void *data)
+{
+ PTCacheMem *pm = data;
+ PTCacheExtra *extra;
+ int i;
+ for (i = 0; i < BPHYS_TOT_DATA; i++) {
+ pm->data[i] = newdataadr(fd, pm->data[i]);
+
+ /* the cache saves non-struct data without DNA */
+ if (pm->data[i] && ptcache_data_struct[i][0]=='\0' && (fd->flags & FD_FLAGS_SWITCH_ENDIAN)) {
+ int tot = (BKE_ptcache_data_size(i) * pm->totpoint) / sizeof(int); /* data_size returns bytes */
+ int *poin = pm->data[i];
+
+ BLI_endian_switch_int32_array(poin, tot);
+ }
+ }
+
+ link_list(fd, &pm->extradata);
+
+ for (extra=pm->extradata.first; extra; extra=extra->next)
+ extra->data = newdataadr(fd, extra->data);
+}
+
+static void direct_link_pointcache(FileData *fd, PointCache *cache)
+{
+ if ((cache->flag & PTCACHE_DISK_CACHE)==0) {
+ link_list_ex(fd, &cache->mem_cache, direct_link_pointcache_cb);
+ }
+ else
+ BLI_listbase_clear(&cache->mem_cache);
+
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe = 0;
+ cache->edit = NULL;
+ cache->free_edit = NULL;
+ cache->cached_frames = NULL;
+}
+
+static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointCache **ocache, int force_disk)
+{
+ if (ptcaches->first) {
+ PointCache *cache= NULL;
+ link_list(fd, ptcaches);
+ for (cache=ptcaches->first; cache; cache=cache->next) {
+ direct_link_pointcache(fd, cache);
+ if (force_disk) {
+ cache->flag |= PTCACHE_DISK_CACHE;
+ cache->step = 1;
+ }
+ }
+
+ *ocache = newdataadr(fd, *ocache);
+ }
+ else if (*ocache) {
+ /* old "single" caches need to be linked too */
+ *ocache = newdataadr(fd, *ocache);
+ direct_link_pointcache(fd, *ocache);
+ if (force_disk) {
+ (*ocache)->flag |= PTCACHE_DISK_CACHE;
+ (*ocache)->step = 1;
+ }
+
+ ptcaches->first = ptcaches->last = *ocache;
+ }
+}
static void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd)
{
@@ -3992,11 +4071,279 @@ static void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd)
pd->f_source = newlibadr(fd, id->lib, pd->f_source);
}
+static void lib_link_particlesettings(FileData *fd, Main *main)
+{
+ ParticleSettings *part;
+ ParticleDupliWeight *dw;
+ MTex *mtex;
+ int a;
+
+ for (part = main->particle.first; part; part = part->id.next) {
+ if (part->id.tag & LIB_TAG_NEED_LINK) {
+ lib_link_animdata(fd, &part->id, part->adt);
+ part->ipo = newlibadr_us(fd, part->id.lib, part->ipo); // XXX deprecated - old animation system
+
+ part->dup_ob = newlibadr(fd, part->id.lib, part->dup_ob);
+ part->dup_group = newlibadr(fd, part->id.lib, part->dup_group);
+ part->eff_group = newlibadr(fd, part->id.lib, part->eff_group);
+ part->bb_ob = newlibadr(fd, part->id.lib, part->bb_ob);
+ part->collision_group = newlibadr(fd, part->id.lib, part->collision_group);
+
+ lib_link_partdeflect(fd, &part->id, part->pd);
+ lib_link_partdeflect(fd, &part->id, part->pd2);
+
+ if (part->effector_weights) {
+ part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
+ }
+ else {
+ part->effector_weights = BKE_add_effector_weights(part->eff_group);
+ }
+
+ if (part->dupliweights.first && part->dup_group) {
+ int index_ok = 0;
+ /* check for old files without indices (all indexes 0) */
+ if (BLI_listbase_is_single(&part->dupliweights)) {
+ /* special case for only one object in the group */
+ index_ok = 1;
+ }
+ else {
+ for (dw = part->dupliweights.first; dw; dw = dw->next) {
+ if (dw->index > 0) {
+ index_ok = 1;
+ break;
+ }
+ }
+ }
+
+ if (index_ok) {
+ /* if we have indexes, let's use them */
+ for (dw = part->dupliweights.first; dw; dw = dw->next) {
+ /* Do not try to restore pointer here, we have to search for group objects in another
+ * separated step.
+ * Reason is, the used group may be linked from another library, which has not yet
+ * been 'lib_linked'.
+ * Since dw->ob is not considered as an object user (it does not make objet directly linked),
+ * we may have no valid way to retrieve it yet.
+ * See T49273. */
+ dw->ob = NULL;
+ }
+ }
+ else {
+ /* otherwise try to get objects from own library (won't work on library linked groups) */
+ for (dw = part->dupliweights.first; dw; dw = dw->next) {
+ dw->ob = newlibadr(fd, part->id.lib, dw->ob);
+ }
+ }
+ }
+ else {
+ BLI_listbase_clear(&part->dupliweights);
+ }
+
+ if (part->boids) {
+ BoidState *state = part->boids->states.first;
+ BoidRule *rule;
+ for (; state; state=state->next) {
+ rule = state->rules.first;
+ for (; rule; rule=rule->next) {
+ switch (rule->type) {
+ case eBoidRuleType_Goal:
+ case eBoidRuleType_Avoid:
+ {
+ BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid*)rule;
+ brga->ob = newlibadr(fd, part->id.lib, brga->ob);
+ break;
+ }
+ case eBoidRuleType_FollowLeader:
+ {
+ BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader*)rule;
+ brfl->ob = newlibadr(fd, part->id.lib, brfl->ob);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ for (a = 0; a < MAX_MTEX; a++) {
+ mtex= part->mtex[a];
+ if (mtex) {
+ mtex->tex = newlibadr_us(fd, part->id.lib, mtex->tex);
+ mtex->object = newlibadr(fd, part->id.lib, mtex->object);
+ }
+ }
+
+ part->id.tag &= ~LIB_TAG_NEED_LINK;
+ }
+ }
+}
+
static void direct_link_partdeflect(PartDeflect *pd)
{
if (pd) pd->rng = NULL;
}
+static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
+{
+ int a;
+
+ part->adt = newdataadr(fd, part->adt);
+ part->pd = newdataadr(fd, part->pd);
+ part->pd2 = newdataadr(fd, part->pd2);
+
+ direct_link_animdata(fd, part->adt);
+ direct_link_partdeflect(part->pd);
+ direct_link_partdeflect(part->pd2);
+
+ part->clumpcurve = newdataadr(fd, part->clumpcurve);
+ if (part->clumpcurve)
+ direct_link_curvemapping(fd, part->clumpcurve);
+ part->roughcurve = newdataadr(fd, part->roughcurve);
+ if (part->roughcurve)
+ direct_link_curvemapping(fd, part->roughcurve);
+
+ part->effector_weights = newdataadr(fd, part->effector_weights);
+ if (!part->effector_weights)
+ part->effector_weights = BKE_add_effector_weights(part->eff_group);
+
+ link_list(fd, &part->dupliweights);
+
+ part->boids = newdataadr(fd, part->boids);
+ part->fluid = newdataadr(fd, part->fluid);
+
+ if (part->boids) {
+ BoidState *state;
+ link_list(fd, &part->boids->states);
+
+ for (state=part->boids->states.first; state; state=state->next) {
+ link_list(fd, &state->rules);
+ link_list(fd, &state->conditions);
+ link_list(fd, &state->actions);
+ }
+ }
+ for (a = 0; a < MAX_MTEX; a++) {
+ part->mtex[a] = newdataadr(fd, part->mtex[a]);
+ }
+}
+
+static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles)
+{
+ ParticleSystem *psys, *psysnext;
+
+ for (psys=particles->first; psys; psys=psysnext) {
+ psysnext = psys->next;
+
+ psys->part = newlibadr_us(fd, id->lib, psys->part);
+ if (psys->part) {
+ ParticleTarget *pt = psys->targets.first;
+
+ for (; pt; pt=pt->next)
+ pt->ob=newlibadr(fd, id->lib, pt->ob);
+
+ psys->parent = newlibadr(fd, id->lib, psys->parent);
+ psys->target_ob = newlibadr(fd, id->lib, psys->target_ob);
+
+ if (psys->clmd) {
+ /* XXX - from reading existing code this seems correct but intended usage of
+ * pointcache /w cloth should be added in 'ParticleSystem' - campbell */
+ psys->clmd->point_cache = psys->pointcache;
+ psys->clmd->ptcaches.first = psys->clmd->ptcaches.last= NULL;
+ psys->clmd->coll_parms->group = newlibadr(fd, id->lib, psys->clmd->coll_parms->group);
+ psys->clmd->modifier.error = NULL;
+ }
+ }
+ else {
+ /* particle modifier must be removed before particle system */
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
+ BLI_remlink(&ob->modifiers, psmd);
+ modifier_free((ModifierData *)psmd);
+
+ BLI_remlink(particles, psys);
+ MEM_freeN(psys);
+ }
+ }
+}
+static void direct_link_particlesystems(FileData *fd, ListBase *particles)
+{
+ ParticleSystem *psys;
+ ParticleData *pa;
+ int a;
+
+ for (psys=particles->first; psys; psys=psys->next) {
+ psys->particles=newdataadr(fd, psys->particles);
+
+ if (psys->particles && psys->particles->hair) {
+ for (a=0, pa=psys->particles; a<psys->totpart; a++, pa++)
+ pa->hair=newdataadr(fd, pa->hair);
+ }
+
+ if (psys->particles && psys->particles->keys) {
+ for (a=0, pa=psys->particles; a<psys->totpart; a++, pa++) {
+ pa->keys= NULL;
+ pa->totkey= 0;
+ }
+
+ psys->flag &= ~PSYS_KEYED;
+ }
+
+ if (psys->particles && psys->particles->boid) {
+ pa = psys->particles;
+ pa->boid = newdataadr(fd, pa->boid);
+ pa->boid->ground = NULL; /* This is purely runtime data, but still can be an issue if left dangling. */
+ for (a = 1, pa++; a < psys->totpart; a++, pa++) {
+ pa->boid = (pa - 1)->boid + 1;
+ pa->boid->ground = NULL;
+ }
+ }
+ else if (psys->particles) {
+ for (a=0, pa=psys->particles; a<psys->totpart; a++, pa++)
+ pa->boid = NULL;
+ }
+
+ psys->fluid_springs = newdataadr(fd, psys->fluid_springs);
+
+ psys->child = newdataadr(fd, psys->child);
+ psys->effectors = NULL;
+
+ link_list(fd, &psys->targets);
+
+ psys->edit = NULL;
+ psys->free_edit = NULL;
+ psys->pathcache = NULL;
+ psys->childcache = NULL;
+ BLI_listbase_clear(&psys->pathcachebufs);
+ BLI_listbase_clear(&psys->childcachebufs);
+ psys->pdd = NULL;
+ psys->renderdata = NULL;
+
+ if (psys->clmd) {
+ psys->clmd = newdataadr(fd, psys->clmd);
+ psys->clmd->clothObject = NULL;
+ psys->clmd->hairdata = NULL;
+
+ psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms);
+ psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms);
+
+ if (psys->clmd->sim_parms) {
+ psys->clmd->sim_parms->effector_weights = NULL;
+ if (psys->clmd->sim_parms->presets > 10)
+ psys->clmd->sim_parms->presets = 0;
+ }
+
+ psys->hair_in_dm = psys->hair_out_dm = NULL;
+ psys->clmd->solver_result = NULL;
+ }
+
+ direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache, 0);
+ if (psys->clmd) {
+ psys->clmd->point_cache = psys->pointcache;
+ }
+
+ psys->tree = NULL;
+ psys->bvhtree = NULL;
+ }
+ return;
+}
+
/* ************ READ MESH ***************** */
static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface)
@@ -4607,6 +4954,7 @@ static void lib_link_object(FileData *fd, Main *main)
ob->soft->effector_weights->group = newlibadr(fd, ob->id.lib, ob->soft->effector_weights->group);
}
+ lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem);
lib_link_modifiers(fd, ob);
if (ob->rigidbody_constraint) {
@@ -4707,6 +5055,8 @@ 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);
+ direct_link_pointcache_list(fd, &clmd->ptcaches, &clmd->point_cache, 0);
+
if (clmd->sim_parms) {
if (clmd->sim_parms->presets > 10)
clmd->sim_parms->presets = 0;
@@ -4752,6 +5102,24 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
smd->domain->effector_weights = newdataadr(fd, smd->domain->effector_weights);
if (!smd->domain->effector_weights)
smd->domain->effector_weights = BKE_add_effector_weights(NULL);
+
+ direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0]), 1);
+
+ /* Smoke uses only one cache from now on, so store pointer convert */
+ if (smd->domain->ptcaches[1].first || smd->domain->point_cache[1]) {
+ if (smd->domain->point_cache[1]) {
+ PointCache *cache = newdataadr(fd, smd->domain->point_cache[1]);
+ if (cache->flag & PTCACHE_FAKE_SMOKE) {
+ /* Smoke was already saved in "new format" and this cache is a fake one. */
+ }
+ else {
+ printf("High resolution smoke cache not available due to pointcache update. Please reset the simulation.\n");
+ }
+ BKE_ptcache_free(cache);
+ }
+ BLI_listbase_clear(&smd->domain->ptcaches[1]);
+ smd->domain->point_cache[1] = NULL;
+ }
}
else if (smd->type == MOD_SMOKE_TYPE_FLOW) {
smd->domain = NULL;
@@ -4761,6 +5129,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
smd->flow->dm = NULL;
smd->flow->verts_old = NULL;
smd->flow->numverts = 0;
+ smd->flow->psys = newdataadr(fd, smd->flow->psys);
}
else if (smd->type == MOD_SMOKE_TYPE_COLL) {
smd->flow = NULL;
@@ -4796,6 +5165,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
for (surface=pmd->canvas->surfaces.first; surface; surface=surface->next) {
surface->canvas = pmd->canvas;
surface->data = NULL;
+ direct_link_pointcache_list(fd, &(surface->ptcaches), &(surface->pointcache), 1);
if (!(surface->effector_weights = newdataadr(fd, surface->effector_weights)))
surface->effector_weights = BKE_add_effector_weights(NULL);
@@ -4805,6 +5175,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
if (pmd->brush) {
pmd->brush = newdataadr(fd, pmd->brush);
pmd->brush->pmd = pmd;
+ pmd->brush->psys = newdataadr(fd, pmd->brush->psys);
pmd->brush->paint_ramp = newdataadr(fd, pmd->brush->paint_ramp);
pmd->brush->vel_ramp = newdataadr(fd, pmd->brush->vel_ramp);
pmd->brush->dm = NULL;
@@ -4859,6 +5230,15 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
direct_link_curvemapping(fd, hmd->curfalloff);
}
}
+ else if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
+
+ psmd->dm_final = NULL;
+ psmd->dm_deformed = NULL;
+ psmd->psys= newdataadr(fd, psmd->psys);
+ psmd->flag &= ~eParticleSystemFlag_psys_updated;
+ psmd->flag |= eParticleSystemFlag_file_loaded;
+ }
else if (md->type == eModifierType_Explode) {
ExplodeModifierData *psmd = (ExplodeModifierData *)md;
@@ -4961,7 +5341,7 @@ static void direct_link_object(FileData *fd, Object *ob)
* See [#34776, #42780] for more information.
*/
if (fd->memfile || (ob->id.tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT))) {
- ob->mode &= ~OB_MODE_EDIT;
+ ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT);
if (!fd->memfile) {
ob->mode &= ~OB_MODE_POSE;
}
@@ -5064,6 +5444,8 @@ static void direct_link_object(FileData *fd, Object *ob)
sb->effector_weights = newdataadr(fd, sb->effector_weights);
if (!sb->effector_weights)
sb->effector_weights = BKE_add_effector_weights(NULL);
+
+ direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache, 0);
}
ob->bsoft = newdataadr(fd, ob->bsoft);
ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
@@ -5081,6 +5463,9 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->rigidbody_constraint = newdataadr(fd, ob->rigidbody_constraint);
if (ob->rigidbody_constraint)
ob->rigidbody_constraint->physics_constraint = NULL;
+
+ link_list(fd, &ob->particlesystem);
+ direct_link_particlesystems(fd, &ob->particlesystem);
link_list(fd, &ob->prop);
for (prop = ob->prop.first; prop; prop = prop->next) {
@@ -5291,6 +5676,8 @@ static void lib_link_scene(FileData *fd, Main *main)
sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
+ sce->toolsettings->particle.shape_object = newlibadr(fd, sce->id.lib, sce->toolsettings->particle.shape_object);
+
for (base = sce->base.first; base; base = next) {
next = base->next;
@@ -5531,6 +5918,9 @@ static void direct_link_scene(FileData *fd, Scene *sce)
direct_link_paint(fd, &sce->toolsettings->imapaint.paint);
sce->toolsettings->imapaint.paintcursor = NULL;
+ sce->toolsettings->particle.paintcursor = NULL;
+ sce->toolsettings->particle.scene = NULL;
+ sce->toolsettings->particle.object = NULL;
sce->toolsettings->gp_sculpt.paintcursor = NULL;
/* in rare cases this is needed, see [#33806] */
@@ -5724,6 +6114,13 @@ static void direct_link_scene(FileData *fd, Scene *sce)
rbw->effector_weights = newdataadr(fd, rbw->effector_weights);
if (!rbw->effector_weights)
rbw->effector_weights = BKE_add_effector_weights(NULL);
+
+ /* link cache */
+ direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, false);
+ /* make sure simulation starts from the beginning after loading file */
+ if (rbw->pointcache) {
+ rbw->ltime = (float)rbw->pointcache->startframe;
+ }
}
sce->preview = direct_link_preview_image(fd, sce->preview);
@@ -7574,6 +7971,7 @@ static const char *dataname(short id_code)
case ID_SO: return "Data from SO";
case ID_NT: return "Data from NT";
case ID_BR: return "Data from BR";
+ case ID_PA: return "Data from PA";
case ID_PAL: return "Data from PAL";
case ID_PC: return "Data from PCRV";
case ID_GD: return "Data from GD";
@@ -7816,6 +8214,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short
case ID_BR:
direct_link_brush(fd, (Brush*)id);
break;
+ case ID_PA:
+ direct_link_particlesettings(fd, (ParticleSettings*)id);
+ break;
case ID_GD:
direct_link_gpencil(fd, (bGPdata *)id);
break;
@@ -8022,6 +8423,7 @@ static void lib_link_all(FileData *fd, Main *main)
lib_link_brush(fd, main);
lib_link_palette(fd, main);
lib_link_paint_curve(fd, main);
+ lib_link_particlesettings(fd, main);
lib_link_movieclip(fd, main);
lib_link_mask(fd, main);
lib_link_linestyle(fd, main);
@@ -8549,6 +8951,58 @@ static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
expand_animdata_nlastrips(fd, mainvar, &nlt->strips);
}
+static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part)
+{
+ int a;
+
+ expand_doit(fd, mainvar, part->dup_ob);
+ expand_doit(fd, mainvar, part->dup_group);
+ expand_doit(fd, mainvar, part->eff_group);
+ expand_doit(fd, mainvar, part->bb_ob);
+ expand_doit(fd, mainvar, part->collision_group);
+
+ if (part->adt)
+ expand_animdata(fd, mainvar, part->adt);
+
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (part->mtex[a]) {
+ expand_doit(fd, mainvar, part->mtex[a]->tex);
+ expand_doit(fd, mainvar, part->mtex[a]->object);
+ }
+ }
+
+ if (part->effector_weights) {
+ expand_doit(fd, mainvar, part->effector_weights->group);
+ }
+
+ if (part->pd) {
+ expand_doit(fd, mainvar, part->pd->tex);
+ expand_doit(fd, mainvar, part->pd->f_source);
+ }
+ if (part->pd2) {
+ expand_doit(fd, mainvar, part->pd2->tex);
+ expand_doit(fd, mainvar, part->pd2->f_source);
+ }
+
+ if (part->boids) {
+ BoidState *state;
+ BoidRule *rule;
+
+ for (state = part->boids->states.first; state; state = state->next) {
+ for (rule = state->rules.first; rule; rule = rule->next) {
+ if (rule->type == eBoidRuleType_Avoid) {
+ BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
+ expand_doit(fd, mainvar, gabr->ob);
+ }
+ else if (rule->type == eBoidRuleType_FollowLeader) {
+ BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
+ expand_doit(fd, mainvar, flbr->ob);
+ }
+ }
+ }
+ }
+}
+
static void expand_group(FileData *fd, Main *mainvar, Group *group)
{
GroupObject *go;
@@ -8851,6 +9305,7 @@ static void expand_object_expandModifiers(
static void expand_object(FileData *fd, Main *mainvar, Object *ob)
{
+ ParticleSystem *psys;
bSensor *sens;
bController *cont;
bActuator *act;
@@ -8907,6 +9362,9 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
if (ob->proxy_group)
expand_doit(fd, mainvar, ob->proxy_group);
+ for (psys = ob->particlesystem.first; psys; psys = psys->next)
+ expand_doit(fd, mainvar, psys->part);
+
for (sens = ob->sensors.first; sens; sens = sens->next) {
if (sens->type == SENS_MESSAGE) {
bMessageSensor *ms = sens->data;
@@ -9277,6 +9735,9 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
case ID_IP:
expand_ipo(fd, mainvar, (Ipo *)id); // XXX deprecated - old animation system
break;
+ case ID_PA:
+ expand_particlesettings(fd, mainvar, (ParticleSettings *)id);
+ break;
case ID_MC:
expand_movieclip(fd, mainvar, (MovieClip *)id);
break;
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 631aec545c2..1956a17d57b 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -53,7 +53,6 @@
#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_fluidsim.h" // NT
-#include "DNA_object_force.h"
#include "DNA_object_types.h"
#include "DNA_view3d_types.h"
#include "DNA_screen_types.h"
@@ -79,6 +78,8 @@
#include "BKE_mesh.h" // for ME_ defines (patching)
#include "BKE_modifier.h"
#include "BKE_multires.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "BKE_texture.h"
@@ -742,6 +743,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
Curve *cu;
Scene *sce;
Tex *tx;
+ ParticleSettings *part;
Object *ob;
//PTCacheID *pid;
//ListBase pidlist;
@@ -872,6 +874,25 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
me->drawflag = ME_DRAWEDGES|ME_DRAWFACES|ME_DRAWCREASES;
}
+ /* particle draw and render types */
+ for (part = main->particle.first; part; part = part->id.next) {
+ if (part->draw_as) {
+ if (part->draw_as == PART_DRAW_DOT) {
+ part->ren_as = PART_DRAW_HALO;
+ part->draw_as = PART_DRAW_REND;
+ }
+ else if (part->draw_as <= PART_DRAW_AXIS) {
+ part->ren_as = PART_DRAW_HALO;
+ }
+ else {
+ part->ren_as = part->draw_as;
+ part->draw_as = PART_DRAW_REND;
+ }
+ }
+ part->path_end = 1.0f;
+ part->clength = 1.0f;
+ }
+
/* set old pointcaches to have disk cache flag */
for (ob = main->object.first; ob; ob = ob->id.next) {
@@ -1115,6 +1136,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
Lamp *la;
World *wo;
Tex *tex;
+ ParticleSettings *part;
bool do_gravity = false;
for (sce = main->scene.first; sce; sce = sce->id.next)
@@ -1175,6 +1197,12 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
+ /* Assign proper global gravity weights for dynamics (only z-coordinate is taken into account) */
+ if (do_gravity) {
+ for (part = main->particle.first; part; part = part->id.next)
+ part->effector_weights->global_gravity = part->acc[2]/-9.81f;
+ }
+
for (ob = main->object.first; ob; ob = ob->id.next) {
ModifierData *md;
@@ -1416,9 +1444,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 9)) {
+ Scene *sce;
Mesh *me;
Object *ob;
+ for (sce = main->scene.first; sce; sce = sce->id.next)
+ if (!sce->toolsettings->particle.selectmode)
+ sce->toolsettings->particle.selectmode = SCE_SELECT_PATH;
+
if (main->versionfile == 250 && main->subversionfile > 1) {
for (me = main->mesh.first; me; me = me->id.next)
multires_load_old_250(me);
@@ -1747,6 +1780,15 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
SEQ_END
}
+ /* particle brush strength factor was changed from int to float */
+ for (sce = main->scene.first; sce; sce = sce->id.next) {
+ ParticleEditSettings *pset = &sce->toolsettings->particle;
+ int a;
+
+ for (a = 0; a < PE_TOT_BRUSH; a++)
+ pset->brush[a].strength /= 100.0f;
+ }
+
for (ma = main->mat.first; ma; ma = ma->id.next)
if (ma->mode & MA_TRACEBLE)
ma->shade_flag |= MA_APPROX_OCCLUSION;
@@ -2153,6 +2195,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 255 || (main->versionfile == 255 && main->subversionfile < 1)) {
Brush *br;
+ ParticleSettings *part;
bScreen *sc;
Object *ob;
@@ -2161,6 +2204,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
br->ob_mode = OB_MODE_ALL_PAINT;
}
+ for (part = main->particle.first; part; part = part->id.next) {
+ if (part->boids)
+ part->boids->pitch = 1.0f;
+
+ part->flag &= ~PART_HAIR_REGROW; /* this was a deprecated flag before */
+ part->kink_amp_clump = 1.f; /* keep old files looking similar */
+ }
+
for (sc = main->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -2378,6 +2429,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
bScreen *sc;
Brush *brush;
Object *ob;
+ ParticleSettings *part;
Material *mat;
int tex_nr, transp_tex;
@@ -2427,6 +2479,12 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
}
+
+ /* particle draw color from material */
+ for (part = main->particle.first; part; part = part->id.next) {
+ if (part->draw & PART_DRAW_MAT_COL)
+ part->draw_col = PART_DRAW_COL_MAT;
+ }
}
if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 6)) {
@@ -2519,6 +2577,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
}
+
+ {
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ /* Initialize particle billboard scale */
+ part->bb_size[0] = part->bb_size[1] = 1.0f;
+ }
+ }
}
if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 1)) {
@@ -2687,6 +2753,15 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 4)) {
{
+ /* Adaptive time step for particle systems */
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ part->courant_target = 0.2f;
+ part->time_flag &= ~PART_TIME_AUTOSF;
+ }
+ }
+
+ {
/* set defaults for obstacle avoidance, recast data */
Scene *sce;
for (sce = main->scene.first; sce; sce = sce->id.next) {
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index 3e4b6534ad8..907baab0aee 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -36,14 +36,12 @@
#include "DNA_camera_types.h"
#include "DNA_cloth_types.h"
#include "DNA_constraint_types.h"
-#include "DNA_dynamicpaint_types.h"
#include "DNA_genfile.h"
#include "DNA_key_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_fluidsim.h" // NT
-#include "DNA_object_force.h"
#include "DNA_object_types.h"
#include "DNA_property_types.h"
#include "DNA_text_types.h"
@@ -66,6 +64,8 @@
#include "BKE_main.h" // for Main
#include "BKE_mesh.h" // for ME_ defines (patching)
#include "BKE_modifier.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_property.h" // for BKE_bproperty_object_get
#include "BKE_scene.h"
#include "BKE_screen.h"
@@ -651,6 +651,20 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
do_versions_nodetree_image_default_alpha_output(ntree);
}
+
+ {
+ /* support old particle dupliobject rotation settings */
+ ParticleSettings *part;
+
+ for (part = main->particle.first; part; part = part->id.next) {
+ if (ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
+ part->draw |= PART_DRAW_ROTATE_OB;
+
+ if (part->rotmode == 0)
+ part->rotmode = PART_ROT_VEL;
+ }
+ }
+ }
}
if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 1)) {
@@ -1127,6 +1141,16 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
+
+
+ if (main->versionfile < 263) {
+ /* Default for old files is to save particle rotations to pointcache */
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ part->flag |= PART_ROTATIONS;
+ }
+ }
+
if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 1)) {
/* file output node paths are now stored in the file info struct instead socket name */
Scene *sce;
@@ -1420,6 +1444,8 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 14)) {
+ ParticleSettings *part;
+
FOREACH_NODETREE(main, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
@@ -1434,6 +1460,12 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
} FOREACH_NODETREE_END
+
+ /* keep compatibility for dupliobject particle size */
+ for (part = main->particle.first; part; part = part->id.next)
+ if (ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR))
+ if ((part->draw & PART_DRAW_ROTATE_OB) == 0)
+ part->draw |= PART_DRAW_NO_SCALE_OB;
}
if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 17)) {
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index c9335f65924..ea654ad6906 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -49,6 +49,7 @@
#include "DNA_mask_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
+#include "DNA_particle_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_actuator_types.h"
#include "DNA_view3d_types.h"
@@ -446,6 +447,22 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
+ if (!MAIN_VERSION_ATLEAST(main, 271, 6)) {
+ Object *ob;
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ ModifierData *md;
+
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
+ if (pmd->psys && pmd->psys->clmd) {
+ pmd->psys->clmd->sim_parms->vel_damping = 1.0f;
+ }
+ }
+ }
+ }
+ }
+
if (!MAIN_VERSION_ATLEAST(main, 272, 0)) {
if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
Scene *scene;
@@ -526,6 +543,16 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
+ if (!MAIN_VERSION_ATLEAST(main, 273, 3)) {
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ if (part->clumpcurve)
+ part->child_flag |= PART_CHILD_USE_CLUMP_CURVE;
+ if (part->roughcurve)
+ part->child_flag |= PART_CHILD_USE_ROUGH_CURVE;
+ }
+ }
+
if (!MAIN_VERSION_ATLEAST(main, 273, 6)) {
if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "float", "bending_damping")) {
Object *ob;
@@ -536,6 +563,39 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
ClothModifierData *clmd = (ClothModifierData *)md;
clmd->sim_parms->bending_damping = 0.5f;
}
+ else if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
+ if (pmd->psys->clmd) {
+ pmd->psys->clmd->sim_parms->bending_damping = 0.5f;
+ }
+ }
+ }
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "ParticleSettings", "float", "clump_noise_size")) {
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ part->clump_noise_size = 1.0f;
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "ParticleSettings", "int", "kink_extra_steps")) {
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ part->kink_extra_steps = 4;
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "MTex", "float", "kinkampfac")) {
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ int a;
+ for (a = 0; a < MAX_MTEX; a++) {
+ MTex *mtex = part->mtex[a];
+ if (mtex) {
+ mtex->kinkampfac = 1.0f;
+ }
}
}
}
@@ -622,6 +682,19 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!MAIN_VERSION_ATLEAST(main, 274, 1)) {
+ /* particle systems need to be forced to redistribute for jitter mode fix */
+ {
+ Object *ob;
+ ParticleSystem *psys;
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (psys = ob->particlesystem.first; psys; psys = psys->next) {
+ if ((psys->pointcache->flag & PTCACHE_BAKED) == 0) {
+ psys->recalc |= PSYS_RECALC_RESET;
+ }
+ }
+ }
+ }
+
/* hysteresis setted to 10% but not actived */
if (!DNA_struct_elem_find(fd->filesdna, "LodLevel", "int", "obhysteresis")) {
Object *ob;
@@ -1016,6 +1089,15 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!MAIN_VERSION_ATLEAST(main, 277, 1)) {
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ ParticleEditSettings *pset = &scene->toolsettings->particle;
+ for (int a = 0; a < PE_TOT_BRUSH; a++) {
+ if (pset->brush[a].strength > 1.0f) {
+ pset->brush[a].strength *= 0.01f;
+ }
+ }
+ }
+
for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
@@ -1173,6 +1255,12 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
ClothModifierData *clmd = (ClothModifierData *)md;
clmd->sim_parms->time_scale = 1.0f;
}
+ else if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
+ if (pmd->psys->clmd) {
+ pmd->psys->clmd->sim_parms->time_scale = 1.0f;
+ }
+ }
}
}
}
@@ -1342,6 +1430,18 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!MAIN_VERSION_ATLEAST(main, 278, 3)) {
+ for (Scene *scene = main->scene.first; scene != NULL; scene = scene->id.next) {
+ if (scene->toolsettings != NULL) {
+ ToolSettings *ts = scene->toolsettings;
+ ParticleEditSettings *pset = &ts->particle;
+ for (int a = 0; a < PE_TOT_BRUSH; a++) {
+ if (pset->brush[a].count == 0) {
+ pset->brush[a].count = 10;
+ }
+ }
+ }
+ }
+
if (!DNA_struct_elem_find(fd->filesdna, "RigidBodyCon", "float", "spring_stiffness_ang_x")) {
Object *ob;
for (ob = main->object.first; ob; ob = ob->id.next) {
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 01ef5d6a606..99d9e140481 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -143,6 +143,13 @@ void BLO_update_defaults_startup_blend(Main *bmain)
ts->gpencil_v2d_align = GP_PROJECT_VIEWSPACE;
ts->gpencil_seq_align = GP_PROJECT_VIEWSPACE;
ts->gpencil_ima_align = GP_PROJECT_VIEWSPACE;
+
+ ParticleEditSettings *pset = &ts->particle;
+ for (int a = 0; a < PE_TOT_BRUSH; a++) {
+ pset->brush[a].strength = 0.5f;
+ pset->brush[a].count = 10;
+ }
+ pset->brush[PE_BRUSH_CUT].strength = 1.0f;
}
scene->gm.lodflag |= SCE_LOD_USE_HYST;
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index f5e9fb240dc..f2d42849bcc 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -59,7 +59,6 @@
#include "DNA_nla_types.h"
#include "DNA_node_types.h"
#include "DNA_object_fluidsim.h" // NT
-#include "DNA_object_force.h"
#include "DNA_object_types.h"
#include "DNA_property_types.h"
#include "DNA_view3d_types.h"
@@ -89,6 +88,8 @@
#include "BKE_main.h" // for Main
#include "BKE_mesh.h" // for ME_ defines (patching)
#include "BKE_modifier.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_property.h" // for BKE_bproperty_object_get
#include "BKE_scene.h"
#include "BKE_sequencer.h"
@@ -494,6 +495,27 @@ static void do_version_ntree_242_2(bNodeTree *ntree)
}
}
+static void do_version_free_effect_245(Effect *eff)
+{
+ PartEff *paf;
+
+ if (eff->type == EFF_PARTICLE) {
+ paf = (PartEff *)eff;
+ if (paf->keys)
+ MEM_freeN(paf->keys);
+ }
+ MEM_freeN(eff);
+}
+
+static void do_version_free_effects_245(ListBase *lb)
+{
+ Effect *eff;
+
+ while ((eff = BLI_pophead(lb))) {
+ do_version_free_effect_245(eff);
+ }
+}
+
static void do_version_constraints_245(ListBase *lb)
{
bConstraint *con;
@@ -2665,10 +2687,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
Image *ima;
Lamp *la;
Material *ma;
+ ParticleSettings *part;
World *wrld;
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) &&
@@ -2749,6 +2774,33 @@ void blo_do_versions_pre250(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(&ob->soft->ptcaches);
+
+ for (psys = ob->particlesystem.first; psys; psys = psys->next) {
+ if (psys->pointcache) {
+ if (psys->pointcache->flag & PTCACHE_BAKED && (psys->pointcache->flag & PTCACHE_DISK_CACHE) == 0) {
+ printf("Old memory cache isn't supported for particles, so re-bake the simulation!\n");
+ psys->pointcache->flag &= ~PTCACHE_BAKED;
+ }
+ }
+ else
+ psys->pointcache = BKE_ptcache_add(&psys->ptcaches);
+ }
+
+ 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(&clmd->ptcaches);
+ clmd->point_cache->step = 1;
+ }
+ }
+ }
+ }
+
/* 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) {
@@ -2794,6 +2846,18 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
ma->strand_min = 1.0f;
}
+ for (part = main->particle.first; part; part = part->id.next) {
+ if (part->ren_child_nbr == 0)
+ part->ren_child_nbr = part->child_nbr;
+
+ if (part->simplify_refsize == 0) {
+ part->simplify_refsize = 1920;
+ part->simplify_rate = 1.0f;
+ part->simplify_transition = 0.1f;
+ part->simplify_viewport = 0.8f;
+ }
+ }
+
for (wrld = main->world.first; wrld; wrld = wrld->id.next) {
if (wrld->ao_approx_error == 0.0f)
wrld->ao_approx_error = 0.25f;
@@ -2933,7 +2997,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 8)) {
+ Scene *sce;
Object *ob;
+ PartEff *paf = NULL;
for (ob = main->object.first; ob; ob = ob->id.next) {
if (ob->soft && ob->soft->keys) {
@@ -2950,6 +3016,145 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
sb->keys = NULL;
sb->totkey = 0;
}
+
+ /* convert old particles to new system */
+ if ((paf = blo_do_version_give_parteff_245(ob))) {
+ ParticleSystem *psys;
+ ModifierData *md;
+ ParticleSystemModifierData *psmd;
+ ParticleSettings *part;
+
+ /* create new particle system */
+ psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+ psys->pointcache = BKE_ptcache_add(&psys->ptcaches);
+
+ part = psys->part = psys_new_settings("ParticleSettings", main);
+
+ /* needed for proper libdata lookup */
+ blo_do_versions_oldnewmap_insert(fd->libmap, psys->part, psys->part, 0);
+ part->id.lib = ob->id.lib;
+
+ part->id.us--;
+ part->id.tag |= (ob->id.tag & LIB_TAG_NEED_LINK);
+
+ psys->totpart = 0;
+ psys->flag = PSYS_CURRENT;
+
+ BLI_addtail(&ob->particlesystem, psys);
+
+ md = modifier_new(eModifierType_ParticleSystem);
+ BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", BLI_listbase_count(&ob->particlesystem));
+ psmd = (ParticleSystemModifierData*) md;
+ psmd->psys = psys;
+ BLI_addtail(&ob->modifiers, md);
+
+ /* convert settings from old particle system */
+ /* general settings */
+ part->totpart = MIN2(paf->totpart, 100000);
+ part->sta = paf->sta;
+ part->end = paf->end;
+ part->lifetime = paf->lifetime;
+ part->randlife = paf->randlife;
+ psys->seed = paf->seed;
+ part->disp = paf->disp;
+ part->omat = paf->mat[0];
+ part->hair_step = paf->totkey;
+
+ part->eff_group = paf->group;
+
+ /* old system didn't interpolate between keypoints at render time */
+ part->draw_step = part->ren_step = 0;
+
+ /* physics */
+ part->normfac = paf->normfac * 25.0f;
+ part->obfac = paf->obfac;
+ part->randfac = paf->randfac * 25.0f;
+ part->dampfac = paf->damp;
+ copy_v3_v3(part->acc, paf->force);
+
+ /* flags */
+ if (paf->stype & PAF_VECT) {
+ if (paf->flag & PAF_STATIC) {
+ /* new hair lifetime is always 100.0f */
+ float fac = paf->lifetime / 100.0f;
+
+ part->draw_as = PART_DRAW_PATH;
+ part->type = PART_HAIR;
+ psys->recalc |= PSYS_RECALC_REDO;
+
+ part->normfac *= fac;
+ part->randfac *= fac;
+ }
+ else {
+ part->draw_as = PART_DRAW_LINE;
+ part->draw |= PART_DRAW_VEL_LENGTH;
+ part->draw_line[1] = 0.04f;
+ }
+ }
+
+ part->rotmode = PART_ROT_VEL;
+
+ part->flag |= (paf->flag & PAF_BSPLINE) ? PART_HAIR_BSPLINE : 0;
+ part->flag |= (paf->flag & PAF_TRAND) ? PART_TRAND : 0;
+ part->flag |= (paf->flag & PAF_EDISTR) ? PART_EDISTR : 0;
+ part->flag |= (paf->flag & PAF_UNBORN) ? PART_UNBORN : 0;
+ part->flag |= (paf->flag & PAF_DIED) ? PART_DIED : 0;
+ part->from |= (paf->flag & PAF_FACE) ? PART_FROM_FACE : 0;
+ part->draw |= (paf->flag & PAF_SHOWE) ? PART_DRAW_EMITTER : 0;
+
+ psys->vgroup[PSYS_VG_DENSITY] = paf->vertgroup;
+ psys->vgroup[PSYS_VG_VEL] = paf->vertgroup_v;
+ psys->vgroup[PSYS_VG_LENGTH] = paf->vertgroup_v;
+
+ /* dupliobjects */
+ if (ob->transflag & OB_DUPLIVERTS) {
+ Object *dup = main->object.first;
+
+ for (; dup; dup = dup->id.next) {
+ if (ob == blo_do_versions_newlibadr(fd, lib, dup->parent)) {
+ part->dup_ob = dup;
+ ob->transflag |= OB_DUPLIPARTS;
+ ob->transflag &= ~OB_DUPLIVERTS;
+
+ part->draw_as = PART_DRAW_OB;
+
+ /* needed for proper libdata lookup */
+ blo_do_versions_oldnewmap_insert(fd->libmap, dup, dup, 0);
+ }
+ }
+ }
+
+ {
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+ if (fluidmd && fluidmd->fss && fluidmd->fss->type == OB_FLUIDSIM_PARTICLE)
+ part->type = PART_FLUID;
+ }
+
+ do_version_free_effects_245(&ob->effect);
+
+ printf("Old particle system converted to new system.\n");
+ }
+ }
+
+ for (sce = main->scene.first; sce; sce = sce->id.next) {
+ ParticleEditSettings *pset = &sce->toolsettings->particle;
+ int a;
+
+ if (pset->brush[0].size == 0) {
+ pset->flag = PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER;
+ pset->emitterdist = 0.25f;
+ pset->totrekey = 5;
+ pset->totaddkey = 5;
+ pset->brushtype = PE_BRUSH_NONE;
+
+ for (a = 0; a < PE_TOT_BRUSH; a++) {
+ pset->brush[a].strength = 50;
+ pset->brush[a].size = 50;
+ pset->brush[a].step = 10;
+ }
+
+ pset->brush[PE_BRUSH_CUT].strength = 100;
+ }
}
}
if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 9)) {
@@ -3041,6 +3246,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
idproperties_fix_group_lengths(main->action);
idproperties_fix_group_lengths(main->nodetree);
idproperties_fix_group_lengths(main->brush);
+ idproperties_fix_group_lengths(main->particle);
}
/* sun/sky */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 169ca10f652..27db83055bb 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -129,6 +129,7 @@
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_packedFile_types.h"
+#include "DNA_particle_types.h"
#include "DNA_property_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
@@ -169,6 +170,7 @@
#include "BKE_subsurf.h"
#include "BKE_modifier.h"
#include "BKE_fcurve.h"
+#include "BKE_pointcache.h"
#include "BKE_mesh.h"
#ifdef USE_NODE_COMPAT_CUSTOMNODES
@@ -1186,6 +1188,210 @@ static void write_userdef(WriteData *wd)
}
}
+static void write_boid_state(WriteData *wd, BoidState *state)
+{
+ BoidRule *rule = state->rules.first;
+
+ writestruct(wd, DATA, BoidState, 1, state);
+
+ for (; rule; rule = rule->next) {
+ switch (rule->type) {
+ case eBoidRuleType_Goal:
+ case eBoidRuleType_Avoid:
+ writestruct(wd, DATA, BoidRuleGoalAvoid, 1, rule);
+ break;
+ case eBoidRuleType_AvoidCollision:
+ writestruct(wd, DATA, BoidRuleAvoidCollision, 1, rule);
+ break;
+ case eBoidRuleType_FollowLeader:
+ writestruct(wd, DATA, BoidRuleFollowLeader, 1, rule);
+ break;
+ case eBoidRuleType_AverageSpeed:
+ writestruct(wd, DATA, BoidRuleAverageSpeed, 1, rule);
+ break;
+ case eBoidRuleType_Fight:
+ writestruct(wd, DATA, BoidRuleFight, 1, rule);
+ break;
+ default:
+ writestruct(wd, DATA, BoidRule, 1, rule);
+ break;
+ }
+ }
+#if 0
+ BoidCondition *cond = state->conditions.first;
+ for (; cond; cond = cond->next) {
+ writestruct(wd, DATA, BoidCondition, 1, cond);
+ }
+#endif
+}
+
+/* update this also to readfile.c */
+static const char *ptcache_data_struct[] = {
+ "", // BPHYS_DATA_INDEX
+ "", // BPHYS_DATA_LOCATION
+ "", // BPHYS_DATA_VELOCITY
+ "", // BPHYS_DATA_ROTATION
+ "", // BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
+ "", // BPHYS_DATA_SIZE:
+ "", // BPHYS_DATA_TIMES:
+ "BoidData" // case BPHYS_DATA_BOIDS:
+};
+static const char *ptcache_extra_struct[] = {
+ "",
+ "ParticleSpring"
+};
+static void write_pointcaches(WriteData *wd, ListBase *ptcaches)
+{
+ PointCache *cache = ptcaches->first;
+ int i;
+
+ for (; cache; cache = cache->next) {
+ writestruct(wd, DATA, PointCache, 1, cache);
+
+ if ((cache->flag & PTCACHE_DISK_CACHE) == 0) {
+ PTCacheMem *pm = cache->mem_cache.first;
+
+ for (; pm; pm = pm->next) {
+ PTCacheExtra *extra = pm->extradata.first;
+
+ writestruct(wd, DATA, PTCacheMem, 1, pm);
+
+ for (i = 0; i < BPHYS_TOT_DATA; i++) {
+ if (pm->data[i] && pm->data_types & (1 << i)) {
+ if (ptcache_data_struct[i][0] == '\0') {
+ writedata(wd, DATA, MEM_allocN_len(pm->data[i]), pm->data[i]);
+ }
+ else {
+ writestruct_id(wd, DATA, ptcache_data_struct[i], pm->totpoint, pm->data[i]);
+ }
+ }
+ }
+
+ for (; extra; extra = extra->next) {
+ if (ptcache_extra_struct[extra->type][0] == '\0') {
+ continue;
+ }
+ writestruct(wd, DATA, PTCacheExtra, 1, extra);
+ writestruct_id(wd, DATA, ptcache_extra_struct[extra->type], extra->totdata, extra->data);
+ }
+ }
+ }
+ }
+}
+static void write_particlesettings(WriteData *wd, ListBase *idbase)
+{
+ ParticleSettings *part;
+ ParticleDupliWeight *dw;
+ GroupObject *go;
+ int a;
+
+ part = idbase->first;
+ while (part) {
+ if (part->id.us > 0 || wd->current) {
+ /* write LibData */
+ writestruct(wd, ID_PA, ParticleSettings, 1, part);
+ write_iddata(wd, &part->id);
+
+ if (part->adt) {
+ write_animdata(wd, part->adt);
+ }
+ writestruct(wd, DATA, PartDeflect, 1, part->pd);
+ writestruct(wd, DATA, PartDeflect, 1, part->pd2);
+ writestruct(wd, DATA, EffectorWeights, 1, part->effector_weights);
+
+ if (part->clumpcurve) {
+ write_curvemapping(wd, part->clumpcurve);
+ }
+ if (part->roughcurve) {
+ write_curvemapping(wd, part->roughcurve);
+ }
+
+ dw = part->dupliweights.first;
+ for (; dw; dw = dw->next) {
+ /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */
+ if (dw->ob != NULL) {
+ dw->index = 0;
+ if (part->dup_group) { /* can be NULL if lining fails or set to None */
+ for (go = part->dup_group->gobject.first; go && go->ob != dw->ob; go = go->next, dw->index++);
+ }
+ }
+ writestruct(wd, DATA, ParticleDupliWeight, 1, dw);
+ }
+
+ if (part->boids && part->phystype == PART_PHYS_BOIDS) {
+ BoidState *state = part->boids->states.first;
+
+ writestruct(wd, DATA, BoidSettings, 1, part->boids);
+
+ for (; state; state = state->next) {
+ write_boid_state(wd, state);
+ }
+ }
+ if (part->fluid && part->phystype == PART_PHYS_FLUID) {
+ writestruct(wd, DATA, SPHFluidSettings, 1, part->fluid);
+ }
+
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (part->mtex[a]) {
+ writestruct(wd, DATA, MTex, 1, part->mtex[a]);
+ }
+ }
+ }
+ part = part->id.next;
+ }
+}
+static void write_particlesystems(WriteData *wd, ListBase *particles)
+{
+ ParticleSystem *psys = particles->first;
+ ParticleTarget *pt;
+ int a;
+
+ for (; psys; psys = psys->next) {
+ writestruct(wd, DATA, ParticleSystem, 1, psys);
+
+ if (psys->particles) {
+ writestruct(wd, DATA, ParticleData, psys->totpart, psys->particles);
+
+ if (psys->particles->hair) {
+ ParticleData *pa = psys->particles;
+
+ for (a = 0; a < psys->totpart; a++, pa++) {
+ writestruct(wd, DATA, HairKey, pa->totkey, pa->hair);
+ }
+ }
+
+ if (psys->particles->boid &&
+ (psys->part->phystype == PART_PHYS_BOIDS))
+ {
+ writestruct(wd, DATA, BoidParticle, psys->totpart, psys->particles->boid);
+ }
+
+ if (psys->part->fluid &&
+ (psys->part->phystype == PART_PHYS_FLUID) &&
+ (psys->part->fluid->flag & SPH_VISCOELASTIC_SPRINGS))
+ {
+ writestruct(wd, DATA, ParticleSpring, psys->tot_fluidsprings, psys->fluid_springs);
+ }
+ }
+ pt = psys->targets.first;
+ for (; pt; pt = pt->next) {
+ writestruct(wd, DATA, ParticleTarget, 1, pt);
+ }
+
+ if (psys->child) {
+ writestruct(wd, DATA, ChildParticle, psys->totchild, psys->child);
+ }
+
+ if (psys->clmd) {
+ writestruct(wd, DATA, ClothModifierData, 1, psys->clmd);
+ writestruct(wd, DATA, ClothSimSettings, 1, psys->clmd->sim_parms);
+ writestruct(wd, DATA, ClothCollSettings, 1, psys->clmd->coll_parms);
+ }
+
+ write_pointcaches(wd, &psys->ptcaches);
+ }
+}
+
static void write_properties(WriteData *wd, ListBase *lb)
{
bProperty *prop;
@@ -1509,6 +1715,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, EffectorWeights, 1, clmd->sim_parms->effector_weights);
+ write_pointcaches(wd, &clmd->ptcaches);
}
else if (md->type == eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData *)md;
@@ -1517,11 +1724,24 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
writestruct(wd, DATA, SmokeDomainSettings, 1, smd->domain);
if (smd->domain) {
+ write_pointcaches(wd, &(smd->domain->ptcaches[0]));
+
+ /* create fake pointcache so that old blender versions can read it */
+ smd->domain->point_cache[1] = BKE_ptcache_add(&smd->domain->ptcaches[1]);
+ smd->domain->point_cache[1]->flag |= PTCACHE_DISK_CACHE | PTCACHE_FAKE_SMOKE;
+ smd->domain->point_cache[1]->step = 1;
+
+ write_pointcaches(wd, &(smd->domain->ptcaches[1]));
if (smd->domain->coba) {
writestruct(wd, DATA, ColorBand, 1, smd->domain->coba);
}
+
+ /* cleanup the fake pointcache */
+ BKE_ptcache_free_list(&smd->domain->ptcaches[1]);
+ smd->domain->point_cache[1] = NULL;
+
writestruct(wd, DATA, EffectorWeights, 1, smd->domain->effector_weights);
}
}
@@ -1550,6 +1770,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
}
/* write caches and effector weights */
for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) {
+ write_pointcaches(wd, &(surface->ptcaches));
+
writestruct(wd, DATA, EffectorWeights, 1, surface->effector_weights);
}
}
@@ -1649,6 +1871,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) {
+ write_pointcaches(wd, &ob->soft->ptcaches);
writestruct(wd, DATA, EffectorWeights, 1, ob->soft->effector_weights);
}
writestruct(wd, DATA, BulletSoftBody, 1, ob->bsoft);
@@ -1665,6 +1888,7 @@ static void write_objects(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, ImageUser, 1, ob->iuser);
}
+ write_particlesystems(wd, &ob->particlesystem);
write_modifiers(wd, &ob->modifiers);
writelist(wd, DATA, LinkData, &ob->pc_ids);
@@ -2611,6 +2835,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
if (sce->rigidbody_world) {
writestruct(wd, DATA, RigidBodyWorld, 1, sce->rigidbody_world);
writestruct(wd, DATA, EffectorWeights, 1, sce->rigidbody_world->effector_weights);
+ write_pointcaches(wd, &(sce->rigidbody_world->ptcaches));
}
write_previews(wd, sce->preview);
@@ -3868,6 +4093,7 @@ static bool write_file_handle(
write_materials(wd, &mainvar->mat);
write_textures(wd, &mainvar->tex);
write_meshes(wd, &mainvar->mesh);
+ write_particlesettings(wd, &mainvar->particle);
write_nodetrees(wd, &mainvar->nodetree);
write_brushes(wd, &mainvar->brush);
write_palettes(wd, &mainvar->palettes);