Merge branch 'master' into blender2.8
[blender.git] / source / blender / makesrna / intern / rna_particle.c
index cf6905ea9146d182c510dde6d231a467faf3e82b..e5bd55f041c3b1959ea33e71fd15c37a3f1c8997 100644 (file)
@@ -32,6 +32,7 @@
 #include <limits.h>
 
 #include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_cloth_types.h"
@@ -45,6 +46,8 @@
 #include "RNA_define.h"
 #include "RNA_enum_types.h"
 
+#include "BKE_mesh.h"
+
 #include "BLI_string_utils.h"
 
 #include "BLT_translation.h"
@@ -112,7 +115,7 @@ static const EnumPropertyItem part_ren_as_items[] = {
        {PART_DRAW_LINE, "LINE", 0, "Line", ""},
        {PART_DRAW_PATH, "PATH", 0, "Path", ""},
        {PART_DRAW_OB, "OBJECT", 0, "Object", ""},
-       {PART_DRAW_GR, "GROUP", 0, "Group", ""},
+       {PART_DRAW_GR, "COLLECTION", 0, "Collection", ""},
        {PART_DRAW_BB, "BILLBOARD", 0, "Billboard", ""},
        {0, NULL, 0, NULL, NULL}
 };
@@ -122,7 +125,7 @@ static const EnumPropertyItem part_hair_ren_as_items[] = {
        {PART_DRAW_NOT, "NONE", 0, "None", ""},
        {PART_DRAW_PATH, "PATH", 0, "Path", ""},
        {PART_DRAW_OB, "OBJECT", 0, "Object", ""},
-       {PART_DRAW_GR, "GROUP", 0, "Group", ""},
+       {PART_DRAW_GR, "COLLECTION", 0, "Collection", ""},
        {0, NULL, 0, NULL, NULL}
 };
 #endif
@@ -136,9 +139,6 @@ static const EnumPropertyItem part_hair_ren_as_items[] = {
 #include "BKE_cloth.h"
 #include "BKE_colortools.h"
 #include "BKE_deform.h"
-#include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_cdderivedmesh.h"
 #include "BKE_effect.h"
 #include "BKE_material.h"
 #include "BKE_modifier.h"
@@ -146,6 +146,9 @@ static const EnumPropertyItem part_hair_ren_as_items[] = {
 #include "BKE_pointcache.h"
 #include "BKE_texture.h"
 
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
 /* use for object space hair get/set */
 static void rna_ParticleHairKey_location_object_info(PointerRNA *ptr, ParticleSystemModifierData **psmd_pt,
                                                      ParticleData **pa_pt)
@@ -178,7 +181,7 @@ static void rna_ParticleHairKey_location_object_info(PointerRNA *ptr, ParticleSy
        for (md = ob->modifiers.first; md; md = md->next) {
                if (md->type == eModifierType_ParticleSystem) {
                        psmd = (ParticleSystemModifierData *) md;
-                       if (psmd && psmd->dm_final && psmd->psys) {
+                       if (psmd && psmd->mesh_final && psmd->psys) {
                                psys = psmd->psys;
                                for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) {
                                        /* hairkeys are stored sequentially in memory, so we can
@@ -205,15 +208,15 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu
        rna_ParticleHairKey_location_object_info(ptr, &psmd, &pa);
 
        if (pa) {
-               DerivedMesh *hairdm = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_dm : NULL;
+               Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL;
 
-               if (hairdm) {
-                       MVert *mvert = CDDM_get_vert(hairdm, pa->hair_index + (hkey - pa->hair));
+               if (hair_mesh) {
+                       MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)];
                        copy_v3_v3(values, mvert->co);
                }
                else {
                        float hairmat[4][4];
-                       psys_mat_hair_to_object(ob, psmd->dm_final, psmd->psys->part->from, pa, hairmat);
+                       psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat);
                        copy_v3_v3(values, hkey->co);
                        mul_m4_v3(hairmat, values);
                }
@@ -233,17 +236,17 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float
        rna_ParticleHairKey_location_object_info(ptr, &psmd, &pa);
 
        if (pa) {
-               DerivedMesh *hairdm = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_dm : NULL;
+               Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL;
 
-               if (hairdm) {
-                       MVert *mvert = CDDM_get_vert(hairdm, pa->hair_index + (hkey - pa->hair));
+               if (hair_mesh) {
+                       MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)];
                        copy_v3_v3(mvert->co, values);
                }
                else {
                        float hairmat[4][4];
                        float imat[4][4];
 
-                       psys_mat_hair_to_object(ob, psmd->dm_final, psmd->psys->part->from, pa, hairmat);
+                       psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat);
                        invert_m4_m4(imat, hairmat);
                        copy_v3_v3(hkey->co, values);
                        mul_m4_v3(imat, hkey->co);
@@ -258,15 +261,15 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey, Object *object, Part
                                              float n_co[3])
 {
 
-       DerivedMesh *hairdm = (modifier->psys->flag & PSYS_HAIR_DYNAMICS) ? modifier->psys->hair_out_dm : NULL;
+       Mesh *hair_mesh = (modifier->psys->flag & PSYS_HAIR_DYNAMICS) ? modifier->psys->hair_out_mesh : NULL;
        if (particle) {
-               if (hairdm) {
-                       MVert *mvert = CDDM_get_vert(hairdm, particle->hair_index + (hairkey - particle->hair));
+               if (hair_mesh) {
+                       MVert *mvert = &hair_mesh->mvert[particle->hair_index + (hairkey - particle->hair)];
                        copy_v3_v3(n_co, mvert->co);
                }
                else {
                        float hairmat[4][4];
-                       psys_mat_hair_to_object(object, modifier->dm_final, modifier->psys->part->from, particle, hairmat);
+                       psys_mat_hair_to_object(object, modifier->mesh_final, modifier->psys->part->from, particle, hairmat);
                        copy_v3_v3(n_co, hairkey->co);
                        mul_m4_v3(hairmat, n_co);
                }
@@ -285,14 +288,14 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, ReportList *repor
        int num = particle->num_dmcache;
        int from = modifier->psys->part->from;
 
-       if (!CustomData_has_layer(&modifier->dm_final->loopData, CD_MLOOPUV)) {
+       if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) {
                BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
                return;
        }
-       DM_ensure_tessface(modifier->dm_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
+       BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
 
        if (num == DMCACHE_NOTFOUND)
-               if (particle->num < modifier->dm_final->getNumTessFaces(modifier->dm_final))
+               if (particle->num < modifier->mesh_final->totface)
                        num = particle->num;
 
        /* get uvco */
@@ -302,8 +305,8 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, ReportList *repor
                        MFace *mface;
                        MTFace *mtface;
 
-                       mface = modifier->dm_final->getTessFaceData(modifier->dm_final, num, CD_MFACE);
-                       mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm_final->faceData, CD_MTFACE, 0);
+                       mface = modifier->mesh_final->mface;
+                       mtface = modifier->mesh_final->mtface;
 
                        if (mface && mtface) {
                                mtface += num;
@@ -324,27 +327,18 @@ static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *o
        ParticleData *pars = NULL;
        ParticleCacheKey *cache = NULL;
        int totchild = 0;
-       int path_nbr = 0;
        int totpart;
        int max_k = 0;
-       int step_nbr = 0;
 
        if (particlesystem == NULL)
                return;
 
        part = particlesystem->part;
        pars = particlesystem->particles;
+       totpart = particlesystem->totcached;
+       totchild = particlesystem->totchildcache;
 
-       if (particlesystem->renderdata) {
-               step_nbr = part->ren_step;
-               totchild = particlesystem->totchild;
-       }
-       else {
-               step_nbr = part->draw_step;
-               totchild = (int)((float)particlesystem->totchild * (float)(part->disp) / 100.0f);
-       }
-
-       if (part == NULL || pars == NULL || !psys_check_enabled(object, particlesystem, particlesystem->renderdata != NULL))
+       if (part == NULL || pars == NULL)
                return;
 
        if (part->ren_as == PART_DRAW_OB || part->ren_as == PART_DRAW_GR || part->ren_as == PART_DRAW_NOT)
@@ -354,47 +348,28 @@ static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *o
        if (part->type == PART_HAIR && !particlesystem->childcache)
                totchild = 0;
 
-       totpart = particlesystem->totpart;
-
-       if (particle_no >= totpart + totchild)
-               return;
-
-       if (part->ren_as == PART_DRAW_PATH && particlesystem->pathcache)
-               path_nbr = 1 << step_nbr;
-       if (part->kink == PART_KINK_SPIRAL)
-               path_nbr += part->kink_extra_steps;
-
        if (particle_no < totpart) {
+               cache = particlesystem->pathcache[particle_no];
+               max_k = (int)cache->segments;
+       }
+       else if (particle_no < totpart + totchild) {
+               cache = particlesystem->childcache[particle_no - totpart];
 
-               if (path_nbr) {
-                       cache = particlesystem->pathcache[particle_no];
+               if (cache->segments < 0)
+                       max_k = 0;
+               else
                        max_k = (int)cache->segments;
-               }
-
        }
        else {
-
-               if (path_nbr) {
-                       cache = particlesystem->childcache[particle_no - totpart];
-
-                       if (cache->segments < 0)
-                               max_k = 0;
-                       else
-                               max_k = (int)cache->segments;
-               }
+               return;
        }
 
-       /*strands key loop data stored in cache + step->co*/
-       if (path_nbr) {
-               if (step >= 0 && step <= path_nbr) {
-                       if (step <= max_k) {
-                               copy_v3_v3(n_co, (cache + step)->co);
-                               mul_m4_v3(particlesystem->imat, n_co);
-                               mul_m4_v3(object->obmat, n_co);
-                       }
-               }
+       /* Strands key loop data stored in cache + step->co. */
+       if (step >= 0 && step <= max_k) {
+               copy_v3_v3(n_co, (cache + step)->co);
+               mul_m4_v3(particlesystem->imat, n_co);
+               mul_m4_v3(object->obmat, n_co);
        }
-
 }
 
 
@@ -450,9 +425,9 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
        int totvert;
        int num = -1;
 
-       DM_ensure_tessface(modifier->dm_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
-       totface = modifier->dm_final->getNumTessFaces(modifier->dm_final);
-       totvert = modifier->dm_final->getNumVerts(modifier->dm_final);
+       BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
+       totface = modifier->mesh_final->totface;
+       totvert = modifier->mesh_final->totvert;
 
        /* 1. check that everything is ok & updated */
        if (!particlesystem || !totface) {
@@ -460,20 +435,13 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
        }
 
        part = particlesystem->part;
-
-       if (particlesystem->renderdata) {
-               totchild = particlesystem->totchild;
-       }
-       else {
-               totchild = (int)((float)particlesystem->totchild * (float)(part->disp) / 100.0f);
-       }
+       totpart = particlesystem->totcached;
+       totchild = particlesystem->totchildcache;
 
        /* can happen for disconnected/global hair */
        if (part->type == PART_HAIR && !particlesystem->childcache)
                totchild = 0;
 
-       totpart = particlesystem->totpart;
-
        if (particle_no >= totpart + totchild)
                return num;
 
@@ -489,7 +457,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
                }
                else if (part->from == PART_FROM_VERT) {
                        if (num != DMCACHE_NOTFOUND && num < totvert) {
-                               MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE);
+                               MFace *mface = modifier->mesh_final->mface;
 
                                *r_fuv = &particle->fuv;
 
@@ -531,7 +499,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
                        }
                        else if (part->from == PART_FROM_VERT) {
                                if (num != DMCACHE_NOTFOUND && num < totvert) {
-                                       MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE);
+                                       MFace *mface = modifier->mesh_final->mface;
 
                                        *r_fuv = &parent->fuv;
 
@@ -555,7 +523,7 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep
                                              ParticleSystemModifierData *modifier, ParticleData *particle,
                                              int particle_no, int uv_no, float r_uv[2])
 {
-       if (!CustomData_has_layer(&modifier->dm_final->loopData, CD_MLOOPUV)) {
+       if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) {
                BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
                zero_v2(r_uv);
                return;
@@ -572,8 +540,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep
                        zero_v2(r_uv);
                }
                else {
-                       MFace *mface = modifier->dm_final->getTessFaceData(modifier->dm_final, num, CD_MFACE);
-                       MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm_final->faceData, CD_MTFACE, uv_no);
+                       MFace *mface = &modifier->mesh_final->mface[num];
+                       MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->mesh_final->fdata, CD_MTFACE, uv_no);
 
                        psys_interpolate_uvs(&mtface[num], mface->v4, *fuv, r_uv);
                }
@@ -584,7 +552,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, R
                                                ParticleSystemModifierData *modifier, ParticleData *particle,
                                                int particle_no, int vcol_no, float r_mcol[3])
 {
-       if (!CustomData_has_layer(&modifier->dm_final->loopData, CD_MLOOPCOL)) {
+       if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPCOL)) {
                BKE_report(reports, RPT_ERROR, "Mesh has no VCol data");
                zero_v3(r_mcol);
                return;
@@ -601,8 +569,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, R
                        zero_v3(r_mcol);
                }
                else {
-                       MFace *mface = modifier->dm_final->getTessFaceData(modifier->dm_final, num, CD_MFACE);
-                       MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm_final->faceData, CD_MCOL, vcol_no);
+                       MFace *mface = &modifier->mesh_final->mface[num];
+                       MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->mesh_final->fdata, CD_MCOL, vcol_no);
                        MCol mcol;
 
                        psys_interpolate_mcol(&mc[num * 4], mface->v4, *fuv, &mcol);
@@ -613,42 +581,18 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, R
        }
 }
 
-static void rna_ParticleSystem_set_resolution(
-        ParticleSystem *particlesystem, Main *bmain, Scene *scene, Object *object, int resolution)
-{
-       if (resolution == eModifierMode_Render) {
-               ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem);
-               float mat[4][4];
-
-               unit_m4(mat);
-
-               psys_render_set(object, particlesystem, mat, mat, 1, 1, 0.f);
-               psmd->flag &= ~eParticleSystemFlag_psys_updated;
-               particle_system_update(bmain, scene, object, particlesystem, true);
-       }
-       else {
-               ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem);
-
-               if (particlesystem->renderdata) {
-                       psys_render_restore(object, particlesystem);
-               }
-
-               psmd->flag &= ~eParticleSystemFlag_psys_updated;
-               particle_system_update(bmain, scene, object, particlesystem, false);
-       }
-}
-
 static void particle_recalc(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr, short flag)
 {
        if (ptr->type == &RNA_ParticleSystem) {
+               Object *ob = ptr->id.data;
                ParticleSystem *psys = (ParticleSystem *)ptr->data;
 
                psys->recalc = flag;
 
-               DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA);
+               DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
        }
        else
-               DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA | flag);
+               DEG_id_tag_update(ptr->id.data, OB_RECALC_DATA | flag);
 
        WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
 }
@@ -659,10 +603,18 @@ static void rna_Particle_redo(Main *bmain, Scene *scene, PointerRNA *ptr)
 
 static void rna_Particle_redo_dependency(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
-       DAG_relations_tag_update(bmain);
+       DEG_relations_tag_update(bmain);
        rna_Particle_redo(bmain, scene, ptr);
 }
 
+static void rna_Particle_redo_count(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+       ParticleSettings *part = (ParticleSettings *)ptr->data;
+       DEG_relations_tag_update(bmain);
+       psys_check_group_weights(part);
+       particle_recalc(bmain, scene, ptr, PSYS_RECALC_REDO);
+}
+
 static void rna_Particle_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
        particle_recalc(bmain, scene, ptr, PSYS_RECALC_RESET);
@@ -670,14 +622,27 @@ static void rna_Particle_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
 
 static void rna_Particle_reset_dependency(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
-       DAG_relations_tag_update(bmain);
+       DEG_relations_tag_update(bmain);
        rna_Particle_reset(bmain, scene, ptr);
 }
 
-static void rna_Particle_change_type(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Particle_change_type(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
 {
-       particle_recalc(bmain, scene, ptr, PSYS_RECALC_RESET | PSYS_RECALC_TYPE);
-       DAG_relations_tag_update(bmain);
+       ParticleSettings *part = ptr->id.data;
+
+       /* Iterating over all object is slow, but no better solution exists at the moment. */
+       for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+               for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
+                       if (psys->part == part) {
+                               psys_changed_type(ob, psys);
+                               psys->recalc |= PSYS_RECALC_RESET;
+                               DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+                       }
+               }
+       }
+
+       WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
+       DEG_relations_tag_update(bmain);
 }
 
 static void rna_Particle_change_physics_type(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -716,7 +681,7 @@ static void rna_Particle_cloth_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
 {
        Object *ob = (Object *)ptr->id.data;
 
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
        WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
 }
 
@@ -761,8 +726,8 @@ static void rna_Particle_target_reset(Main *bmain, Scene *UNUSED(scene), Pointer
 
                psys->recalc = PSYS_RECALC_RESET;
 
-               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
-               DAG_relations_tag_update(bmain);
+               DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+               DEG_relations_tag_update(bmain);
        }
 
        WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
@@ -777,7 +742,7 @@ static void rna_Particle_target_redo(Main *UNUSED(bmain), Scene *UNUSED(scene),
 
                psys->recalc = PSYS_RECALC_REDO;
 
-               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+               DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
        }
 }
@@ -790,7 +755,7 @@ static void rna_Particle_hair_dynamics_update(Main *bmain, Scene *scene, Pointer
        if (psys && !psys->clmd) {
                psys->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth);
                psys->clmd->sim_parms->goalspring = 0.0f;
-               psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL | CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
+               psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESIST_SPRING_COMPRESS;
                psys->clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_SELF;
                rna_Particle_redo(bmain, scene, ptr);
        }
@@ -798,9 +763,10 @@ static void rna_Particle_hair_dynamics_update(Main *bmain, Scene *scene, Pointer
                WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
        }
 
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
-       DAG_relations_tag_update(bmain);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_relations_tag_update(bmain);
 }
+
 static PointerRNA rna_particle_settings_get(PointerRNA *ptr)
 {
        ParticleSystem *psys = (ParticleSystem *)ptr->data;
@@ -811,6 +777,7 @@ static PointerRNA rna_particle_settings_get(PointerRNA *ptr)
 
 static void rna_particle_settings_set(PointerRNA *ptr, PointerRNA value)
 {
+       Object *ob = ptr->id.data;
        ParticleSystem *psys = (ParticleSystem *)ptr->data;
        int old_type = 0;
 
@@ -825,8 +792,9 @@ static void rna_particle_settings_set(PointerRNA *ptr, PointerRNA value)
        if (psys->part) {
                id_us_plus(&psys->part->id);
                psys_check_boid_data(psys);
-               if (old_type != psys->part->type)
-                       psys->recalc |= PSYS_RECALC_TYPE;
+               if (old_type != psys->part->type) {
+                       psys_changed_type(ob, psys);
+               }
        }
 }
 static void rna_Particle_abspathtime_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -1164,6 +1132,9 @@ static void rna_ParticleDupliWeight_active_index_set(struct PointerRNA *ptr, int
 
 static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *str)
 {
+       ParticleSettings *part = (ParticleSettings *)ptr->id.data;
+       psys_find_group_weights(part);
+
        ParticleDupliWeight *dw = ptr->data;
 
        if (dw->ob)
@@ -1591,7 +1562,7 @@ static void rna_def_particle_dupliweight(BlenderRNA *brna)
        PropertyRNA *prop;
 
        srna = RNA_def_struct(brna, "ParticleDupliWeight", NULL);
-       RNA_def_struct_ui_text(srna, "Particle Dupliobject Weight", "Weight of a particle dupliobject in a group");
+       RNA_def_struct_ui_text(srna, "Particle Dupliobject Weight", "Weight of a particle dupliobject in a collection");
        RNA_def_struct_sdna(srna, "ParticleDupliWeight");
 
        prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
@@ -2333,11 +2304,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Size", "Show particle size");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       prop = RNA_def_property(srna, "use_render_emitter", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_EMITTER);
-       RNA_def_property_ui_text(prop, "Emitter", "Render emitter Object also");
-       RNA_def_property_update(prop, 0, "rna_Particle_redo");
-
        prop = RNA_def_property(srna, "show_health", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_HEALTH);
        RNA_def_property_ui_text(prop, "Health", "Draw boid health");
@@ -2358,29 +2324,29 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Number", "Show particle number");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       prop = RNA_def_property(srna, "use_group_pick_random", PROP_BOOLEAN, PROP_NONE);
+       prop = RNA_def_property(srna, "use_collection_pick_random", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_RAND_GR);
-       RNA_def_property_ui_text(prop, "Pick Random", "Pick objects from group randomly");
+       RNA_def_property_ui_text(prop, "Pick Random", "Pick objects from collection randomly");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       prop = RNA_def_property(srna, "use_group_count", PROP_BOOLEAN, PROP_NONE);
+       prop = RNA_def_property(srna, "use_collection_count", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_COUNT_GR);
-       RNA_def_property_ui_text(prop, "Use Count", "Use object multiple times in the same group");
-       RNA_def_property_update(prop, 0, "rna_Particle_redo");
+       RNA_def_property_ui_text(prop, "Use Count", "Use object multiple times in the same collection");
+       RNA_def_property_update(prop, 0, "rna_Particle_redo_count");
 
-       prop = RNA_def_property(srna, "use_global_dupli", PROP_BOOLEAN, PROP_NONE);
+       prop = RNA_def_property(srna, "use_global_instance", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_GLOBAL_OB);
        RNA_def_property_ui_text(prop, "Global", "Use object's global coordinates for duplication");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       prop = RNA_def_property(srna, "use_rotation_dupli", PROP_BOOLEAN, PROP_NONE);
+       prop = RNA_def_property(srna, "use_rotation_instance", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_ROTATE_OB);
        RNA_def_property_ui_text(prop, "Rotation",
                                 "Use object's rotation for duplication (global x-axis is aligned "
                                 "particle rotation axis)");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       prop = RNA_def_property(srna, "use_scale_dupli", PROP_BOOLEAN, PROP_NONE);
+       prop = RNA_def_property(srna, "use_scale_instance", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_negative_sdna(prop, NULL, "draw", PART_DRAW_NO_SCALE_OB);
        RNA_def_property_ui_text(prop, "Scale", "Use object's scale for duplication");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
@@ -2395,9 +2361,9 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Speed", "Multiply line length by particle speed");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       prop = RNA_def_property(srna, "use_whole_group", PROP_BOOLEAN, PROP_NONE);
+       prop = RNA_def_property(srna, "use_whole_collection", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_WHOLE_GR);
-       RNA_def_property_ui_text(prop, "Whole Group", "Use whole group at once");
+       RNA_def_property_ui_text(prop, "Whole Collection", "Use whole collection at once");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
        prop = RNA_def_property(srna, "use_strand_primitive", PROP_BOOLEAN, PROP_NONE);
@@ -2405,7 +2371,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Strand Render", "Use the strand primitive for rendering");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       prop = RNA_def_property(srna, "draw_method", PROP_ENUM, PROP_NONE);
+       prop = RNA_def_property(srna, "display_method", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "draw_as");
        RNA_def_property_enum_items(prop, part_draw_as_items);
        RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_draw_as_itemf");
@@ -2419,16 +2385,17 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Particle Rendering", "How particles are rendered");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       prop = RNA_def_property(srna, "draw_color", PROP_ENUM, PROP_NONE);
+       prop = RNA_def_property(srna, "display_color", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "draw_col");
        RNA_def_property_enum_items(prop, draw_col_items);
        RNA_def_property_ui_text(prop, "Draw Color", "Draw additional particle data as a color");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       prop = RNA_def_property(srna, "draw_size", PROP_INT, PROP_PIXEL);
+       prop = RNA_def_property(srna, "display_size", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "draw_size");
        RNA_def_property_range(prop, 0, 1000);
        RNA_def_property_ui_range(prop, 0, 100, 1, -1);
-       RNA_def_property_ui_text(prop, "Draw Size", "Size of particles on viewport in pixels (0=default)");
+       RNA_def_property_ui_text(prop, "Draw Size", "Size of particles on viewport in BU");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
        prop = RNA_def_property(srna, "child_type", PROP_ENUM, PROP_NONE);
@@ -2437,7 +2404,8 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Children From", "Create child particles");
        RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
 
-       prop = RNA_def_property(srna, "draw_step", PROP_INT, PROP_NONE);
+       prop = RNA_def_property(srna, "display_step", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "draw_step");
        RNA_def_property_range(prop, 0, 10);
        RNA_def_property_ui_range(prop, 0, 7, 1, -1);
        RNA_def_property_ui_text(prop, "Steps", "How many steps paths are drawn with (power of 2)");
@@ -2477,7 +2445,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_range(prop, 0, 50);
        RNA_def_property_ui_text(prop, "Pixel", "How many pixels path has to cover to make another render segment");
 
-       prop = RNA_def_property(srna, "draw_percentage", PROP_INT, PROP_PERCENTAGE);
+       prop = RNA_def_property(srna, "display_percentage", PROP_INT, PROP_PERCENTAGE);
        RNA_def_property_int_sdna(prop, NULL, "disp");
        RNA_def_property_range(prop, 0, 100);
        RNA_def_property_ui_text(prop, "Display", "Percentage of particles to display in 3D view");
@@ -2586,33 +2554,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Billboard Velocity Tail", "Scale billboards by velocity");
        RNA_def_property_update(prop, 0, "rna_Particle_redo");
 
-       /* simplification */
-       prop = RNA_def_property(srna, "use_simplify", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "simplify_flag", PART_SIMPLIFY_ENABLE);
-       RNA_def_property_ui_text(prop, "Child Simplification",
-                                "Remove child strands as the object becomes smaller on the screen");
-
-       prop = RNA_def_property(srna, "use_simplify_viewport", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "simplify_flag", PART_SIMPLIFY_VIEWPORT);
-       RNA_def_property_ui_text(prop, "Viewport", "");
-
-       prop = RNA_def_property(srna, "simplify_refsize", PROP_INT, PROP_PIXEL);
-       RNA_def_property_int_sdna(prop, NULL, "simplify_refsize");
-       RNA_def_property_range(prop, 1, SHRT_MAX);
-       RNA_def_property_ui_text(prop, "Reference Size", "Reference size in pixels, after which simplification begins");
-
-       prop = RNA_def_property(srna, "simplify_rate", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_range(prop, 0.0f, 1.0f);
-       RNA_def_property_ui_text(prop, "Rate", "Speed of simplification");
-
-       prop = RNA_def_property(srna, "simplify_transition", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_range(prop, 0.0f, 1.0f);
-       RNA_def_property_ui_text(prop, "Transition", "Transition period for fading out strands");
-
-       prop = RNA_def_property(srna, "simplify_viewport", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_range(prop, 0.0f, 0.999f);
-       RNA_def_property_ui_text(prop, "Rate", "Speed of Simplification");
-
        /* general values */
        prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "sta"); /*optional if prop names are the same */
@@ -2839,9 +2780,11 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Random Size", "Give the particle size a random variation");
        RNA_def_property_update(prop, 0, "rna_Particle_reset");
 
-       prop = RNA_def_property(srna, "collision_group", PROP_POINTER, PROP_NONE);
+       prop = RNA_def_property(srna, "collision_collection", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "Collection");
+       RNA_def_property_pointer_sdna(prop, NULL, "collision_group");
        RNA_def_property_flag(prop, PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Collision Group", "Limit colliders to this Group");
+       RNA_def_property_ui_text(prop, "Collision Collection", "Limit colliders to this collection");
        RNA_def_property_update(prop, 0, "rna_Particle_reset_dependency");
 
        /* global physical properties */
@@ -3150,35 +3093,35 @@ static void rna_def_particle_settings(BlenderRNA *brna)
                                       "(must use same subsurf level for viewport and render for correct results)");
        RNA_def_property_update(prop, 0, "rna_Particle_change_type");
 
-       /* draw objects & groups */
-       prop = RNA_def_property(srna, "dupli_group", PROP_POINTER, PROP_NONE);
+       /* draw objects & collections */
+       prop = RNA_def_property(srna, "instance_collection", PROP_POINTER, PROP_NONE);
        RNA_def_property_pointer_sdna(prop, NULL, "dup_group");
-       RNA_def_property_struct_type(prop, "Group");
+       RNA_def_property_struct_type(prop, "Collection");
        RNA_def_property_flag(prop, PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Dupli Group", "Show Objects in this Group in place of particles");
-       RNA_def_property_update(prop, 0, "rna_Particle_redo");
+       RNA_def_property_ui_text(prop, "Dupli Collection", "Show Objects in this collection in place of particles");
+       RNA_def_property_update(prop, 0, "rna_Particle_redo_count");
 
-       prop = RNA_def_property(srna, "dupli_weights", PROP_COLLECTION, PROP_NONE);
+       prop = RNA_def_property(srna, "instance_weights", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "dupliweights", NULL);
        RNA_def_property_struct_type(prop, "ParticleDupliWeight");
-       RNA_def_property_ui_text(prop, "Dupli Group Weights", "Weights for all of the objects in the dupli group");
+       RNA_def_property_ui_text(prop, "Dupli Collection Weights", "Weights for all of the objects in the dupli collection");
 
-       prop = RNA_def_property(srna, "active_dupliweight", PROP_POINTER, PROP_NONE);
+       prop = RNA_def_property(srna, "active_instanceweight", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "ParticleDupliWeight");
        RNA_def_property_pointer_funcs(prop, "rna_ParticleDupliWeight_active_get", NULL, NULL, NULL);
        RNA_def_property_ui_text(prop, "Active Dupli Object", "");
 
-       prop = RNA_def_property(srna, "active_dupliweight_index", PROP_INT, PROP_UNSIGNED);
+       prop = RNA_def_property(srna, "active_instanceweight_index", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_funcs(prop, "rna_ParticleDupliWeight_active_index_get",
                                   "rna_ParticleDupliWeight_active_index_set",
                                   "rna_ParticleDupliWeight_active_index_range");
        RNA_def_property_ui_text(prop, "Active Dupli Object Index", "");
 
-       prop = RNA_def_property(srna, "dupli_object", PROP_POINTER, PROP_NONE);
+       prop = RNA_def_property(srna, "instance_object", PROP_POINTER, PROP_NONE);
        RNA_def_property_pointer_sdna(prop, NULL, "dup_ob");
        RNA_def_property_struct_type(prop, "Object");
        RNA_def_property_flag(prop, PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Dupli Object", "Show this Object in place of particles");
+       RNA_def_property_ui_text(prop, "Instance Object", "Show this Object in place of particles");
        RNA_def_property_update(prop, 0, "rna_Particle_redo_dependency");
 
        prop = RNA_def_property(srna, "billboard_object", PROP_POINTER, PROP_NONE);
@@ -3239,6 +3182,38 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Twist Curve", "Curve defining twist");
        RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+       /* hair shape */
+       prop = RNA_def_property(srna, "use_close_tip", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "shape_flag", PART_SHAPE_CLOSE_TIP);
+       RNA_def_property_ui_text(prop, "Close Tip", "Set tip radius to zero");
+       RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* TODO: Only need to tell the render engine to update. */
+
+       prop = RNA_def_property(srna, "shape", PROP_FLOAT, PROP_FACTOR);
+       RNA_def_property_range(prop, -1.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Shape", "Strand shape parameter");
+       RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* TODO: Only need to tell the render engine to update. */
+
+       prop = RNA_def_property(srna, "root_radius", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "rad_root");
+       RNA_def_property_range(prop, 0.0f, FLT_MAX);
+       RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 2);
+       RNA_def_property_ui_text(prop, "Root", "Strand width at the root");
+       RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* TODO: Only need to tell the render engine to update. */
+
+       prop = RNA_def_property(srna, "tip_radius", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "rad_tip");
+       RNA_def_property_range(prop, 0.0f, FLT_MAX);
+       RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 2);
+       RNA_def_property_ui_text(prop, "Tip", "Strand width at the tip");
+       RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* TODO: Only need to tell the render engine to update. */
+
+       prop = RNA_def_property(srna, "radius_scale", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "rad_scale");
+       RNA_def_property_range(prop, 0.0f, FLT_MAX);
+       RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 2);
+       RNA_def_property_ui_text(prop, "Scaling", "Multiplier of radius properties");
+       RNA_def_property_update(prop, 0, "rna_Particle_redo"); /* TODO: Only need to tell the render engine to update. */
 }
 
 static void rna_def_particle_target(BlenderRNA *brna)
@@ -3309,12 +3284,6 @@ static void rna_def_particle_system(BlenderRNA *brna)
        FunctionRNA *func;
        PropertyRNA *parm;
 
-       static const EnumPropertyItem resolution_items[] = {
-               {eModifierMode_Realtime, "PREVIEW", 0, "Preview", "Apply modifier preview settings"},
-               {eModifierMode_Render, "RENDER", 0, "Render", "Apply modifier render settings"},
-               {0, NULL, 0, NULL, NULL}
-       };
-
        srna = RNA_def_struct(brna, "ParticleSystem", NULL);
        RNA_def_struct_ui_text(srna, "Particle System", "Particle system in an object");
        RNA_def_struct_ui_icon(srna, ICON_PARTICLE_DATA);
@@ -3338,11 +3307,13 @@ static void rna_def_particle_system(BlenderRNA *brna)
        prop = RNA_def_property(srna, "particles", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "particles", "totpart");
        RNA_def_property_struct_type(prop, "Particle");
+       RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
        RNA_def_property_ui_text(prop, "Particles", "Particles generated by the particle system");
 
        prop = RNA_def_property(srna, "child_particles", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "child", "totchild");
        RNA_def_property_struct_type(prop, "ChildParticle");
+       RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
        RNA_def_property_ui_text(prop, "Child Particles", "Child particles generated by the particle system");
 
        prop = RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED);
@@ -3625,14 +3596,6 @@ static void rna_def_particle_system(BlenderRNA *brna)
 
        RNA_def_struct_path_func(srna, "rna_ParticleSystem_path");
 
-       /* set viewport or render resolution */
-       func = RNA_def_function(srna, "set_resolution", "rna_ParticleSystem_set_resolution");
-       RNA_def_function_ui_description(func, "Set the resolution to use for the number of particles");
-       RNA_def_function_flag(func, FUNC_USE_MAIN);
-       RNA_def_pointer(func, "scene", "Scene", "", "Scene");
-       RNA_def_pointer(func, "object", "Object", "", "Object");
-       RNA_def_enum(func, "resolution", resolution_items, 0, "", "Resolution settings to apply");
-
        /* extract cached hair location data */
        func = RNA_def_function(srna, "co_hair", "rna_ParticleSystem_co_hair");
        RNA_def_function_ui_description(func, "Obtain cache hair data");