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

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