Particle System: ported most DerivedMesh → Mesh
authorSybren A. Stüvel <sybren@stuvel.eu>
Tue, 15 May 2018 11:26:40 +0000 (13:26 +0200)
committerSybren A. Stüvel <sybren@stuvel.eu>
Wed, 16 May 2018 14:31:38 +0000 (16:31 +0200)
There are a few places where DerivedMesh is still used, most notably
when calling the (not yet ported) cloth simulation. There is also still
the use of Object.derivedDeform and Object.derivedFinal. Those places are
marked with a TODO.

Some functions in the editors module were copied to accept Mesh. Those
already had 'mesh' in the name; the copies are suffixed with '__real_mesh'
for easy renaming later when the DM-based functionality is removed.

22 files changed:
source/blender/alembic/intern/abc_hair.cc
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_distribute.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenloader/intern/readfile.c
source/blender/draw/intern/draw_cache_impl_particles.c
source/blender/editors/include/ED_mesh.h
source/blender/editors/mesh/editmesh_utils.c
source/blender/editors/mesh/mesh_mirror.c
source/blender/editors/mesh/meshtools.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/physics/particle_object.c
source/blender/editors/transform/transform_conversions.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesdna/DNA_particle_types.h
source/blender/makesrna/intern/rna_particle.c
source/blender/modifiers/intern/MOD_explode.c
source/blender/modifiers/intern/MOD_particleinstance.c
source/blender/modifiers/intern/MOD_particlesystem.c

index b31a185..e7cc474 100644 (file)
@@ -73,7 +73,7 @@ void AbcHairWriter::do_write()
 
        ParticleSystemModifierData *psmd = psys_get_modifier(m_object, m_psys);
 
-       if (!psmd->dm_final) {
+       if (!psmd->mesh_final) {
                return;
        }
 
index 7525b49..25b91be 100644 (file)
@@ -31,6 +31,9 @@
  *  \ingroup bke
  */
 
+/* defines BLI_INLINE */
+#include "BLI_utildefines.h"
+
 struct ID;
 struct BMeshCreateParams;
 struct BMeshFromMeshParams;
@@ -503,6 +506,20 @@ enum {
 void BKE_mesh_batch_cache_dirty(struct Mesh *me, int mode);
 void BKE_mesh_batch_cache_free(struct Mesh *me);
 
+
+/* Inlines */
+
+/* This is a copy of DM_origindex_mface_mpoly().
+ * Instead of -1 that function uses ORIGINDEX_NONE as defined in BKE_customdata.h,
+ * but I don't want to force every user of BKE_mesh.h to also include that file.
+ * ~~ Sybren */
+BLI_INLINE int BKE_mesh_origindex_mface_mpoly(
+        const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i)
+{
+       const int j = index_mf_to_mpoly[i];
+       return (j != -1) ? (index_mp_to_orig ? index_mp_to_orig[j] : j) : -1;
+}
+
 #ifdef __cplusplus
 }
 #endif
index 097532f..b6a87ae 100644 (file)
@@ -137,7 +137,7 @@ typedef struct ParticleCacheKey {
 typedef struct ParticleThreadContext {
        /* shared */
        struct ParticleSimulationData sim;
-       struct DerivedMesh *dm;
+       struct Mesh *mesh;
        struct Material *ma;
 
        /* distribution */
@@ -413,34 +413,34 @@ void psys_free_particles(struct ParticleSystem *psys);
 void psys_free_children(struct ParticleSystem *psys);
 
 void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, bool velocity);
-void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float vec[3]);
-void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
-void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
-void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
+void psys_vec_rot_to_face(struct Mesh *mesh, struct ParticleData *pa, float vec[3]);
+void psys_mat_hair_to_object(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4]);
+void psys_mat_hair_to_global(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4]);
+void psys_mat_hair_to_orco(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4]);
 
 float psys_get_dietime_from_cache(struct PointCache *cache, int index);
 
 void psys_free_pdd(struct ParticleSystem *psys);
 
-float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
+float *psys_cache_vgroup(struct Mesh *mesh, struct ParticleSystem *psys, int vgroup);
 void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra);
 void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface,
                            float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3],
                            float orco[3]);
-float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values);
+float psys_particle_value_from_verts(struct Mesh *mesh, short from, struct ParticleData *pa, float *values);
 void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time);
 
 /* BLI_bvhtree_ray_cast callback */
 void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit);
-void psys_particle_on_dm(struct DerivedMesh *dm_final, int from, int index, int index_dmcache,
+void psys_particle_on_dm(struct Mesh *mesh_final, int from, int index, int index_dmcache,
                          const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
                          float orco[3]);
 
 /* particle_system.c */
 void distribute_particles(struct ParticleSimulationData *sim, int from);
 void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
-void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm_final, struct DerivedMesh *dm_deformed, struct ParticleSystem *psys);
-int psys_particle_dm_face_lookup(struct DerivedMesh *dm_final, struct DerivedMesh *dm_deformed, int findex, const float fw[4], struct LinkNode **poly_nodes);
+void psys_calc_dmcache(struct Object *ob, struct Mesh *mesh_final, struct Mesh *mesh_deformed, struct ParticleSystem *psys);
+int psys_particle_dm_face_lookup(struct Mesh *mesh_final, struct Mesh *mesh_deformed, int findex, const float fw[4], struct LinkNode **poly_nodes);
 
 void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
 
index fc6a42e..bced9a1 100644 (file)
@@ -375,14 +375,12 @@ void BKE_object_free_caches(Object *object)
        for (md = object->modifiers.first; md != NULL; md = md->next) {
                if (md->type == eModifierType_ParticleSystem) {
                        ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
-                       if (psmd->dm_final != NULL) {
-                               psmd->dm_final->needsFree = 1;
-                               psmd->dm_final->release(psmd->dm_final);
-                               psmd->dm_final = NULL;
-                               if (psmd->dm_deformed != NULL) {
-                                       psmd->dm_deformed->needsFree = 1;
-                                       psmd->dm_deformed->release(psmd->dm_deformed);
-                                       psmd->dm_deformed = NULL;
+                       if (psmd->mesh_final) {
+                               BKE_id_free(NULL, psmd->mesh_final);
+                               psmd->mesh_final = NULL;
+                               if (psmd->mesh_deformed) {
+                                       BKE_id_free(NULL, psmd->mesh_deformed);
+                                       psmd->mesh_deformed = NULL;
                                }
                                psmd->flag |= eParticleSystemFlag_file_loaded;
                                update_flag |= OB_RECALC_DATA;
@@ -875,7 +873,7 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int f
        if (psys->clmd) {
                psysn->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth);
                modifier_copyData_ex((ModifierData *)psys->clmd, (ModifierData *)psysn->clmd, flag);
-               psys->hair_in_dm = psys->hair_out_dm = NULL;
+               psys->hair_in_mesh = psys->hair_out_mesh = NULL;
        }
 
        BLI_duplicatelist(&psysn->targets, &psys->targets);
index ed09e89..2e07616 100644 (file)
@@ -51,6 +51,7 @@
 #include "BLI_noise.h"
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
+#include "BLI_kdopbvh.h"
 #include "BLI_kdtree.h"
 #include "BLI_rand.h"
 #include "BLI_task.h"
@@ -80,7 +81,7 @@
 #include "BKE_library_remap.h"
 #include "BKE_modifier.h"
 #include "BKE_mesh.h"
-#include "BKE_cdderivedmesh.h"
+#include "BKE_cdderivedmesh.h"  /* for weight_to_rgb() */
 #include "BKE_pointcache.h"
 #include "BKE_scene.h"
 #include "BKE_deform.h"
@@ -110,7 +111,7 @@ void psys_init_rng(void)
 
 static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx,
                                           ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
-static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par,
+static void get_cpa_texture(Mesh *mesh, ParticleSystem *psys, ParticleSettings *part, ParticleData *par,
                                                        int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra);
 
 /* few helpers for countall etc. */
@@ -497,13 +498,13 @@ void free_hair(Object *UNUSED(ob), ParticleSystem *psys, int dynamics)
                }
        }
 
-       if (psys->hair_in_dm)
-               psys->hair_in_dm->release(psys->hair_in_dm);
-       psys->hair_in_dm = NULL;
+       if (psys->hair_in_mesh)
+               BKE_id_free(NULL, psys->hair_in_mesh);
+       psys->hair_in_mesh = NULL;
 
-       if (psys->hair_out_dm)
-               psys->hair_out_dm->release(psys->hair_out_dm);
-       psys->hair_out_dm = NULL;
+       if (psys->hair_out_mesh)
+               BKE_id_free(NULL, psys->hair_out_mesh);
+       psys->hair_out_mesh = NULL;
 }
 void free_keyed_keys(ParticleSystem *psys)
 {
@@ -713,7 +714,7 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic
 typedef struct ParticleInterpolationData {
        HairKey *hkey[2];
 
-       DerivedMesh *dm;
+       Mesh *mesh;
        MVert *mvert[2];
 
        int keyed;
@@ -847,8 +848,8 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic
                pind->birthtime = key->time;
                pind->dietime = (key + pa->totkey - 1)->time;
 
-               if (pind->dm) {
-                       pind->mvert[0] = CDDM_get_vert(pind->dm, pa->hair_index);
+               if (pind->mesh) {
+                       pind->mvert[0] = &pind->mesh->mvert[pa->hair_index];
                        pind->mvert[1] = pind->mvert[0] + 1;
                }
        }
@@ -957,7 +958,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
                edit_to_particle(keys + 1, pind->ekey[0]);
                edit_to_particle(keys + 2, pind->ekey[1]);
        }
-       else if (pind->dm) {
+       else if (pind->mesh) {
                pind->mvert[0] = pind->mvert[1] - 1;
                mvert_to_particle(keys + 1, pind->mvert[0], pind->hkey[0]);
                mvert_to_particle(keys + 2, pind->mvert[1], pind->hkey[1]);
@@ -982,7 +983,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
                        else
                                edit_to_particle(keys, pind->ekey[0]);
                }
-               else if (pind->dm) {
+               else if (pind->mesh) {
                        if (pind->hkey[0] != pa->hair)
                                mvert_to_particle(keys, pind->mvert[0] - 1, pind->hkey[0] - 1);
                        else
@@ -1001,7 +1002,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
                        else
                                edit_to_particle(keys + 3, pind->ekey[1]);
                }
-               else if (pind->dm) {
+               else if (pind->mesh) {
                        if (pind->hkey[1] != pa->hair + pa->totkey - 1)
                                mvert_to_particle(keys + 3, pind->mvert[1] + 1, pind->hkey[1] + 1);
                        else
@@ -1227,7 +1228,7 @@ void psys_interpolate_mcol(const MCol *mcol, int quad, const float w[4], MCol *m
        }
 }
 
-static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, const float fw[4], const float *values)
+static float psys_interpolate_value_from_verts(Mesh *mesh, short from, int index, const float fw[4], const float *values)
 {
        if (values == 0 || index == -1)
                return 0.0;
@@ -1238,7 +1239,7 @@ static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int
                case PART_FROM_FACE:
                case PART_FROM_VOLUME:
                {
-                       MFace *mf = dm->getTessFaceData(dm, index, CD_MFACE);
+                       MFace *mf = &mesh->mface[index];
                        return interpolate_particle_value(values[mf->v1], values[mf->v2], values[mf->v3], values[mf->v4], fw, mf->v4);
                }
                        
@@ -1288,7 +1289,7 @@ static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, const float w[4
  * \return the DM tessface index.
  */
 int psys_particle_dm_face_lookup(
-        DerivedMesh *dm_final, DerivedMesh *dm_deformed,
+        Mesh *mesh_final, Mesh *mesh_deformed,
         int findex_orig, const float fw[4], struct LinkNode **poly_nodes)
 {
        MFace *mtessface_final;
@@ -1300,36 +1301,36 @@ int psys_particle_dm_face_lookup(
        const int *index_mf_to_mpoly = NULL;
        const int *index_mp_to_orig = NULL;
 
-       const int totface_final = dm_final->getNumTessFaces(dm_final);
-       const int totface_deformed = dm_deformed ? dm_deformed->getNumTessFaces(dm_deformed) : totface_final;
+       const int totface_final = mesh_final->totface;
+       const int totface_deformed = mesh_deformed ? mesh_deformed->totface : totface_final;
 
        if (ELEM(0, totface_final, totface_deformed)) {
                return DMCACHE_NOTFOUND;
        }
 
-       index_mf_to_mpoly = dm_final->getTessFaceDataArray(dm_final, CD_ORIGINDEX);
-       index_mp_to_orig = dm_final->getPolyDataArray(dm_final, CD_ORIGINDEX);
+       index_mf_to_mpoly = CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX);
+       index_mp_to_orig = CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX);
        BLI_assert(index_mf_to_mpoly);
 
-       if (dm_deformed) {
-               index_mf_to_mpoly_deformed = dm_deformed->getTessFaceDataArray(dm_deformed, CD_ORIGINDEX);
+       if (mesh_deformed) {
+               index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_deformed->fdata, CD_ORIGINDEX);
        }
        else {
-               BLI_assert(dm_final->deformedOnly);
+               BLI_assert(mesh_final->runtime.deformed_only);
                index_mf_to_mpoly_deformed = index_mf_to_mpoly;
        }
        BLI_assert(index_mf_to_mpoly_deformed);
 
        pindex_orig = index_mf_to_mpoly_deformed[findex_orig];
 
-       if (dm_deformed == NULL) {
-               dm_deformed = dm_final;
+       if (mesh_deformed == NULL) {
+               mesh_deformed = mesh_final;
        }
 
        index_mf_to_mpoly_deformed = NULL;
 
-       mtessface_final = dm_final->getTessFaceArray(dm_final);
-       osface_final = dm_final->getTessFaceDataArray(dm_final, CD_ORIGSPACE);
+       mtessface_final = mesh_final->mface;
+       osface_final = CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE);
 
        if (osface_final == NULL) {
                /* Assume we don't need osface_final data, and we get a direct 1-1 mapping... */
@@ -1342,7 +1343,7 @@ int psys_particle_dm_face_lookup(
                        return DMCACHE_NOTFOUND;
                }
        }
-       else if (findex_orig >= dm_deformed->getNumTessFaces(dm_deformed)) {
+       else if (findex_orig >= mesh_deformed->totface) {
                return DMCACHE_NOTFOUND;  /* index not in the original mesh */
        }
 
@@ -1371,7 +1372,7 @@ int psys_particle_dm_face_lookup(
        else { /* if we have no node, try every face */
                for (int findex_dst = 0; findex_dst < totface_final; findex_dst++) {
                        /* If current tessface from 'final' DM and orig tessface (given by index) map to the same orig poly... */
-                       if (DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, findex_dst) == pindex_orig) {
+                       if (BKE_mesh_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, findex_dst) == pindex_orig) {
                                faceuv = osface_final[findex_dst].uv;
 
                                /* check that this intersects - Its possible this misses :/ -
@@ -1391,22 +1392,22 @@ int psys_particle_dm_face_lookup(
        return DMCACHE_NOTFOUND;
 }
 
-static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float UNUSED(foffset), int *mapindex, float mapfw[4])
+static int psys_map_index_on_dm(Mesh *mesh, int from, int index, int index_dmcache, const float fw[4], float UNUSED(foffset), int *mapindex, float mapfw[4])
 {
        if (index < 0)
                return 0;
 
-       if (dm->deformedOnly || index_dmcache == DMCACHE_ISCHILD) {
+       if (mesh->runtime.deformed_only || index_dmcache == DMCACHE_ISCHILD) {
                /* for meshes that are either only deformed or for child particles, the
                 * index and fw do not require any mapping, so we can directly use it */
                if (from == PART_FROM_VERT) {
-                       if (index >= dm->getNumVerts(dm))
+                       if (index >= mesh->totvert)
                                return 0;
 
                        *mapindex = index;
                }
                else { /* FROM_FACE/FROM_VOLUME */
-                       if (index >= dm->getNumTessFaces(dm))
+                       if (index >= mesh->totface)
                                return 0;
 
                        *mapindex = index;
@@ -1418,7 +1419,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_
                 * to their new location, which means a different index, and for faces
                 * also a new face interpolation weights */
                if (from == PART_FROM_VERT) {
-                       if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache > dm->getNumVerts(dm))
+                       if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache > mesh->totvert)
                                return 0;
 
                        *mapindex = index_dmcache;
@@ -1431,15 +1432,15 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_
 
                        i = index_dmcache;
 
-                       if (i == DMCACHE_NOTFOUND || i >= dm->getNumTessFaces(dm))
+                       if (i == DMCACHE_NOTFOUND || i >= mesh->totface)
                                return 0;
 
                        *mapindex = i;
 
                        /* modify the original weights to become
                         * weights for the derived mesh face */
-                       osface = dm->getTessFaceDataArray(dm, CD_ORIGSPACE);
-                       mface = dm->getTessFaceData(dm, i, CD_MFACE);
+                       osface = CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE);
+                       mface = &mesh->mface[i];
 
                        if (osface == NULL)
                                mapfw[0] = mapfw[1] = mapfw[2] = mapfw[3] = 0.0f;
@@ -1452,7 +1453,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_
 }
 
 /* interprets particle data to get a point on a mesh in object space */
-void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_dmcache,
+void psys_particle_on_dm(Mesh *mesh_final, int from, int index, int index_dmcache,
                          const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
                          float orco[3])
 {
@@ -1460,7 +1461,7 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d
        float (*orcodata)[3];
        int mapindex;
 
-       if (!psys_map_index_on_dm(dm_final, from, index, index_dmcache, fw, foffset, &mapindex, mapfw)) {
+       if (!psys_map_index_on_dm(mesh_final, from, index, index_dmcache, fw, foffset, &mapindex, mapfw)) {
                if (vec) { vec[0] = vec[1] = vec[2] = 0.0; }
                if (nor) { nor[0] = nor[1] = 0.0; nor[2] = 1.0; }
                if (orco) { orco[0] = orco[1] = orco[2] = 0.0; }
@@ -1470,13 +1471,13 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d
                return;
        }
 
-       orcodata = dm_final->getVertDataArray(dm_final, CD_ORCO);
+       orcodata = CustomData_get_layer(&mesh_final->vdata, CD_ORCO);
 
        if (from == PART_FROM_VERT) {
-               dm_final->getVertCo(dm_final, mapindex, vec);
+               copy_v3_v3(vec, mesh_final->mvert[mapindex].co);
 
                if (nor) {
-                       dm_final->getVertNo(dm_final, mapindex, nor);
+                       normal_short_to_float_v3(nor, mesh_final->mvert[mapindex].no);
                        normalize_v3(nor);
                }
 
@@ -1499,9 +1500,9 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d
                MTFace *mtface;
                MVert *mvert;
 
-               mface = dm_final->getTessFaceData(dm_final, mapindex, CD_MFACE);
-               mvert = dm_final->getVertDataArray(dm_final, CD_MVERT);
-               mtface = CustomData_get_layer(&dm_final->faceData, CD_MTFACE);
+               mface = &mesh_final->mface[mapindex];
+               mvert = mesh_final->mvert;
+               mtface = mesh_final->mtface;
 
                if (mtface)
                        mtface += mapindex;
@@ -1520,15 +1521,15 @@ void psys_particle_on_dm(DerivedMesh *dm_final, int from, int index, int index_d
        }
 }
 
-float psys_particle_value_from_verts(DerivedMesh *dm, short from, ParticleData *pa, float *values)
+float psys_particle_value_from_verts(Mesh *mesh, short from, ParticleData *pa, float *values)
 {
        float mapfw[4];
        int mapindex;
 
-       if (!psys_map_index_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, &mapindex, mapfw))
+       if (!psys_map_index_on_dm(mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, &mapindex, mapfw))
                return 0.0f;
        
-       return psys_interpolate_value_from_verts(dm, from, mapindex, mapfw, values);
+       return psys_interpolate_value_from_verts(mesh, from, mapindex, mapfw, values);
 }
 
 ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys)
@@ -1615,7 +1616,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in
                               float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
                               float orco[3])
 {
-       if (psmd && psmd->dm_final) {
+       if (psmd && psmd->mesh_final) {
                if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) {
                        if (vec)
                                copy_v3_v3(vec, fuv);
@@ -1625,7 +1626,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in
                        return;
                }
                /* we cant use the num_dmcache */
-               psys_particle_on_dm(psmd->dm_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco);
+               psys_particle_on_dm(psmd->mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco);
        }
        else
                psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco);
@@ -1841,7 +1842,7 @@ static void offset_child(ChildParticle *cpa, ParticleKey *par, float *par_rot, P
 
        add_v3_v3(child->co, par->co);
 }
-float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup)
+float *psys_cache_vgroup(Mesh *mesh, ParticleSystem *psys, int vgroup)
 {
        float *vg = 0;
 
@@ -1850,9 +1851,9 @@ float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup)
 
        }
        else if (psys->vgroup[vgroup]) {
-               MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
+               MDeformVert *dvert = mesh->dvert;
                if (dvert) {
-                       int totvert = dm->getNumVerts(dm), i;
+                       int totvert = mesh->totvert, i;
                        vg = MEM_callocN(sizeof(float) * totvert, "vg_cache");
                        if (psys->vg_neg & (1 << vgroup)) {
                                for (i = 0; i < totvert; i++)
@@ -1892,7 +1893,7 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params
                psys_particle_on_emitter(sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco);
 
                /* Check if particle doesn't exist because of texture influence. Insert only existing particles into kdtree. */
-               get_cpa_texture(sim->psmd->dm_final, psys, part, psys->particles + cpa->pa[0], p, cpa->num, cpa->fuv, orco, &ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra);
+               get_cpa_texture(sim->psmd->mesh_final, psys, part, psys->particles + cpa->pa[0], p, cpa->num, cpa->fuv, orco, &ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra);
 
                if (ptex.exist >= psys_frand(psys, p + 24)) {
                        BLI_kdtree_insert(tree, p, orco);
@@ -1967,15 +1968,15 @@ static bool psys_thread_context_init_path(
        psys->lattice_deform_data = psys_create_lattice_deform_data(&ctx->sim);
 
        /* cache all relevant vertex groups if they exist */
-       ctx->vg_length = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_LENGTH);
-       ctx->vg_clump = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_CLUMP);
-       ctx->vg_kink = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_KINK);
-       ctx->vg_rough1 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH1);
-       ctx->vg_rough2 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH2);
-       ctx->vg_roughe = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGHE);
-       ctx->vg_twist = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_TWIST);
+       ctx->vg_length = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_LENGTH);
+       ctx->vg_clump = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_CLUMP);
+       ctx->vg_kink = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_KINK);
+       ctx->vg_rough1 = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_ROUGH1);
+       ctx->vg_rough2 = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_ROUGH2);
+       ctx->vg_roughe = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_ROUGHE);
+       ctx->vg_twist = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_TWIST);
        if (psys->part->flag & PART_CHILD_EFFECT)
-               ctx->vg_effector = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_EFFECTOR);
+               ctx->vg_effector = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_EFFECTOR);
 
        /* prepare curvemapping tables */
        if ((part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && part->clumpcurve) {
@@ -2127,7 +2128,7 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp
                for (w = 0; w < 4; w++)
                        sub_v3_v3v3(off1[w], co, key[w]->co);
 
-               psys_mat_hair_to_global(ob, ctx->sim.psmd->dm_final, psys->part->from, pa, hairmat);
+               psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat);
        }
        else {
                ParticleData *pa = psys->particles + cpa->parent;
@@ -2158,13 +2159,13 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp
                        : pa->num_dmcache;
 
                /* XXX hack to avoid messed up particle num and subsequent crash (#40733) */
-               if (cpa_num > ctx->sim.psmd->dm_final->getNumTessFaces(ctx->sim.psmd->dm_final))
+               if (cpa_num > ctx->sim.psmd->mesh_final->totface)
                        cpa_num = 0;
                cpa_fuv = pa->fuv;
 
                psys_particle_on_emitter(ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco);
 
-               psys_mat_hair_to_global(ob, ctx->sim.psmd->dm_final, psys->part->from, pa, hairmat);
+               psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat);
        }
 
        child_keys->segments = ctx->segments;
@@ -2414,7 +2415,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
        ParticleSettings *part = psys->part;
        ParticleCacheKey *ca, **cache;
 
-       DerivedMesh *hair_dm = (psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) ? psys->hair_out_dm : NULL;
+       Mesh *hair_mesh = (psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) ? psys->hair_out_mesh : NULL;
        
        ParticleKey result;
        
@@ -2459,15 +2460,15 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
 
        if ((psys->flag & PSYS_GLOBAL_HAIR) == 0) {
                if ((psys->part->flag & PART_CHILD_EFFECT) == 0)
-                       vg_effector = psys_cache_vgroup(psmd->dm_final, psys, PSYS_VG_EFFECTOR);
+                       vg_effector = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_EFFECTOR);
                
                if (!psys->totchild)
-                       vg_length = psys_cache_vgroup(psmd->dm_final, psys, PSYS_VG_LENGTH);
+                       vg_length = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_LENGTH);
        }
 
        /* ensure we have tessfaces to be used for mapping */
        if (part->from != PART_FROM_VERT) {
-               DM_ensure_tessface(psmd->dm_final);
+               BKE_mesh_tessface_ensure(psmd->mesh_final);
        }
 
        /*---first main loop: create all actual particles' paths---*/
@@ -2476,14 +2477,14 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
                        psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f);
                        pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p));
                        if (vg_length)
-                               pa_length *= psys_particle_value_from_verts(psmd->dm_final, part->from, pa, vg_length);
+                               pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length);
                }
 
                pind.keyed = keyed;
                pind.cache = baked ? psys->pointcache : NULL;
                pind.epoint = NULL;
                pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
-               pind.dm = hair_dm;
+               pind.mesh = hair_mesh;
 
                memset(cache[p], 0, sizeof(*cache[p]) * (segments + 1));
 
@@ -2493,7 +2494,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
                init_particle_interpolation(sim->ob, sim->psys, pa, &pind);
 
                /* hairmat is needed for for non-hair particle too so we get proper rotations */
-               psys_mat_hair_to_global(sim->ob, psmd->dm_final, psys->part->from, pa, hairmat);
+               psys_mat_hair_to_global(sim->ob, psmd->mesh_final, psys->part->from, pa, hairmat);
                copy_v3_v3(rotmat[0], hairmat[2]);
                copy_v3_v3(rotmat[1], hairmat[1]);
                copy_v3_v3(rotmat[2], hairmat[0]);
@@ -2525,7 +2526,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
 
                        /* dynamic hair is in object space */
                        /* keyed and baked are already in global space */
-                       if (hair_dm)
+                       if (hair_mesh)
                                mul_m4_v3(sim->ob->obmat, ca->co);
                        else if (!keyed && !baked && !(psys->flag & PSYS_GLOBAL_HAIR))
                                mul_m4_v3(hairmat, ca->co);
@@ -2548,7 +2549,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
                        if ((psys->part->flag & PART_CHILD_EFFECT) == 0) {
                                float effector = 1.0f;
                                if (vg_effector)
-                                       effector *= psys_particle_value_from_verts(psmd->dm_final, psys->part->from, pa, vg_effector);
+                                       effector *= psys_particle_value_from_verts(psmd->mesh_final, psys->part->from, pa, vg_effector);
 
                                sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co);
                                length = len_v3(vec);
@@ -2685,7 +2686,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
                pind.cache = NULL;
                pind.epoint = point;
                pind.bspline = psys ? (psys->part->flag & PART_HAIR_BSPLINE) : 0;
-               pind.dm = NULL;
+               pind.mesh = NULL;
 
 
                /* should init_particle_interpolation set this ? */
@@ -2705,7 +2706,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
                init_particle_interpolation(ob_eval, psys_eval, pa, &pind);
 
                if (psys_eval) {
-                       psys_mat_hair_to_global(ob_eval, psmd_eval->dm_final, psys->part->from, pa, hairmat);
+                       psys_mat_hair_to_global(ob_eval, psmd_eval->mesh_final, psys->part->from, pa, hairmat);
                        copy_v3_v3(rotmat[0], hairmat[2]);
                        copy_v3_v3(rotmat[1], hairmat[1]);
                        copy_v3_v3(rotmat[2], hairmat[0]);
@@ -2913,7 +2914,7 @@ static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat
        cross_v3_v3v3(mat[0], mat[1], mat[2]);
 }
 
-static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[4][4], int orco)
+static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4][4], int orco)
 {
        float v[3][3];
        MFace *mface;
@@ -2921,72 +2922,72 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m
        float (*orcodata)[3];
 
        int i = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num : pa->num_dmcache;
-       if (i == -1 || i >= dm->getNumTessFaces(dm)) { unit_m4(mat); return; }
+       if (i == -1 || i >= mesh->totface) { unit_m4(mat); return; }
 
-       mface = dm->getTessFaceData(dm, i, CD_MFACE);
-       osface = dm->getTessFaceData(dm, i, CD_ORIGSPACE);
+       mface = &mesh->mface[i];
+       osface = CustomData_get(&mesh->fdata, i, CD_ORIGSPACE);
        
-       if (orco && (orcodata = dm->getVertDataArray(dm, CD_ORCO))) {
+       if (orco && (orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO))) {
                copy_v3_v3(v[0], orcodata[mface->v1]);
                copy_v3_v3(v[1], orcodata[mface->v2]);
                copy_v3_v3(v[2], orcodata[mface->v3]);
 
                /* ugly hack to use non-transformed orcos, since only those
                 * give symmetric results for mirroring in particle mode */
-               if (DM_get_vert_data_layer(dm, CD_ORIGINDEX))
+               if (CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX))
                        BKE_mesh_orco_verts_transform(ob->data, v, 3, 1);
        }
        else {
-               dm->getVertCo(dm, mface->v1, v[0]);
-               dm->getVertCo(dm, mface->v2, v[1]);
-               dm->getVertCo(dm, mface->v3, v[2]);
+               copy_v3_v3(v[0], mesh->mvert[mface->v1].co);
+               copy_v3_v3(v[1], mesh->mvert[mface->v2].co);
+               copy_v3_v3(v[2], mesh->mvert[mface->v3].co);
        }
 
        triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat);
 }
 
-void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4])
+void psys_mat_hair_to_object(Object *UNUSED(ob), Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4])
 {
        float vec[3];
 
        /* can happen when called from a different object's modifier */
-       if (!dm) {
+       if (!mesh) {
                unit_m4(hairmat);
                return;
        }
        
-       psys_face_mat(0, dm, pa, hairmat, 0);
-       psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0);
+       psys_face_mat(0, mesh, pa, hairmat, 0);
+       psys_particle_on_dm(mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0);
        copy_v3_v3(hairmat[3], vec);
 }
 
-void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4])
+void psys_mat_hair_to_orco(Object *ob, Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4])
 {
        float vec[3], orco[3];
 
-       psys_face_mat(ob, dm, pa, hairmat, 1);
-       psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco);
+       psys_face_mat(ob, mesh, pa, hairmat, 1);
+       psys_particle_on_dm(mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco);
 
        /* see psys_face_mat for why this function is called */
-       if (DM_get_vert_data_layer(dm, CD_ORIGINDEX))
+       if (CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX))
                BKE_mesh_orco_verts_transform(ob->data, &orco, 1, 1);
        copy_v3_v3(hairmat[3], orco);
 }
 
-void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float vec[3])
+void psys_vec_rot_to_face(Mesh *mesh, ParticleData *pa, float vec[3])
 {
        float mat[4][4];
 
-       psys_face_mat(0, dm, pa, mat, 0);
+       psys_face_mat(0, mesh, pa, mat, 0);
        transpose_m4(mat); /* cheap inverse for rotation matrix */
        mul_mat3_m4_v3(mat, vec);
 }
 
-void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4])
+void psys_mat_hair_to_global(Object *ob, Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4])
 {
        float facemat[4][4];
 
-       psys_mat_hair_to_object(ob, dm, from, pa, facemat);
+       psys_mat_hair_to_object(ob, mesh, from, pa, facemat);
 
        mul_m4_m4m4(hairmat, ob->obmat, facemat);
 }
@@ -3268,25 +3269,25 @@ void BKE_particlesettings_make_local(Main *bmain, ParticleSettings *part, const
 /*                     Textures                                                        */
 /************************************************/
 
-static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const float fuv[4],
+static int get_particle_uv(Mesh *mesh, ParticleData *pa, int index, const float fuv[4],
                            char *name, float *texco, bool from_vert)
 {
        MFace *mf;
        MTFace *tf;
        int i;
        
-       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, name);
+       tf = CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name);
 
        if (tf == NULL)
-               tf = CustomData_get_layer(&dm->faceData, CD_MTFACE);
+               tf = mesh->mtface;
 
        if (tf == NULL)
                return 0;
 
        if (pa) {
                i = ELEM(pa->num_dmcache, DMCACHE_NOTFOUND, DMCACHE_ISCHILD) ? pa->num : pa->num_dmcache;
-               if ((!from_vert && i >= dm->getNumTessFaces(dm)) ||
-                   (from_vert && i >= dm->getNumVerts(dm)))
+               if ((!from_vert && i >= mesh->totface) ||
+                   (from_vert && i >= mesh->totvert))
                {
                        i = -1;
                }
@@ -3302,12 +3303,12 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const f
        }
        else {
                if (from_vert) {
-                       mf = dm->getTessFaceDataArray(dm, CD_MFACE);
+                       mf = mesh->mface;
 
                        /* This finds the first face to contain the emitting vertex,
                         * this is not ideal, but is mostly fine as UV seams generally
                         * map to equal-colored parts of a texture */
-                       for (int j = 0; j < dm->getNumTessFaces(dm); j++, mf++) {
+                       for (int j = 0; j < mesh->totface; j++, mf++) {
                                if (ELEM(i, mf->v1, mf->v2, mf->v3, mf->v4)) {
                                        i = j;
                                        break;
@@ -3315,7 +3316,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const f
                        }
                }
                else {
-                       mf = dm->getTessFaceData(dm, i, CD_MFACE);
+                       mf = &mesh->mface[i];
                }
 
                psys_interpolate_uvs(&tf[i], mf->v4, fuv, texco);
@@ -3350,7 +3351,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const f
                CLAMP(pvalue, -1.0f, 1.0f);                                           \
        } (void)0
 
-static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra)
+static void get_cpa_texture(Mesh *mesh, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra)
 {
        MTex *mtex, **mtexp = part->mtex;
        int m;
@@ -3384,7 +3385,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
                                                mul_m4_v3(mtex->object->imat, texvec);
                                        break;
                                case TEXCO_UV:
-                                       if (fw && get_particle_uv(dm, NULL, face_index, fw, mtex->uvname,
+                                       if (fw && get_particle_uv(mesh, NULL, face_index, fw, mtex->uvname,
                                                                  texvec, (part->from == PART_FROM_VERT)))
                                        {
                                                break;
@@ -3462,7 +3463,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
                                                mul_m4_v3(mtex->object->imat, texvec);
                                        break;
                                case TEXCO_UV:
-                                       if (get_particle_uv(sim->psmd->dm_final, pa, 0, pa->fuv, mtex->uvname,
+                                       if (get_particle_uv(sim->psmd->mesh_final, pa, 0, pa->fuv, mtex->uvname,
                                                            texvec, (part->from == PART_FROM_VERT)))
                                        {
                                                break;
@@ -3592,28 +3593,28 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
        ParticleSystem *psys = ctx->sim.psys;
        int i = cpa - psys->child;
 
-       get_cpa_texture(ctx->dm, psys, part, psys->particles + cpa->pa[0], i, cpa_num, cpa_fuv, orco, ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra);
+       get_cpa_texture(ctx->mesh, psys, part, psys->particles + cpa->pa[0], i, cpa_num, cpa_fuv, orco, ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra);
 
 
        if (ptex->exist < psys_frand(psys, i + 24))
                return;
 
        if (ctx->vg_length)
-               ptex->length *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_length);
+               ptex->length *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_length);
        if (ctx->vg_clump)
-               ptex->clump *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_clump);
+               ptex->clump *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_clump);
        if (ctx->vg_kink)
-               ptex->kink_freq *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_kink);
+               ptex->kink_freq *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_kink);
        if (ctx->vg_rough1)
-               ptex->rough1 *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough1);
+               ptex->rough1 *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough1);
        if (ctx->vg_rough2)
-               ptex->rough2 *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough2);
+               ptex->rough2 *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough2);
        if (ctx->vg_roughe)
-               ptex->roughe *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_roughe);
+               ptex->roughe *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_roughe);
        if (ctx->vg_effector)
-               ptex->effector *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector);
+               ptex->effector *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector);
        if (ctx->vg_twist)
-               ptex->twist *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_twist);
+               ptex->twist *= psys_interpolate_value_from_verts(ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_twist);
 }
 /* get's hair (or keyed) particles state at the "path time" specified in state->time */
 void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, const bool vel)
@@ -3666,17 +3667,17 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
                        pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
                        /* pind.dm disabled in editmode means we don't get effectors taken into
                         * account when subdividing for instance */
-                       pind.dm = psys_in_edit_mode(sim->depsgraph, psys) ? NULL : psys->hair_out_dm;
+                       pind.mesh = psys_in_edit_mode(sim->depsgraph, psys) ? NULL : psys->hair_out_mesh; /* XXX Sybren EEK */
                        init_particle_interpolation(sim->ob, psys, pa, &pind);
                        do_particle_interpolation(psys, p, pa, t, &pind, state);
 
-                       if (pind.dm) {
+                       if (pind.mesh) {
                                mul_m4_v3(sim->ob->obmat, state->co);
                                mul_mat3_m4_v3(sim->ob->obmat, state->vel);
                        }
                        else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) {
                                if ((pa->flag & PARS_REKEY) == 0) {
-                                       psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, part->from, pa, hairmat);
+                                       psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, part->from, pa, hairmat);
                                        mul_m4_v3(hairmat, state->co);
                                        mul_mat3_m4_v3(hairmat, state->vel);
 
@@ -3743,7 +3744,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
 
                                psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco);
                                if (part->type == PART_HAIR)
-                                       psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat);
+                                       psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat);
                                else
                                        unit_m4(hairmat);
 
@@ -3764,7 +3765,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
                                psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco);
                                if (part->type == PART_HAIR) {
                                        psys_particle_on_emitter(psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco);
-                                       psys_mat_hair_to_global(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat);
+                                       psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat);
                                }
                                else {
                                        copy_v3_v3(orco, cpa->fuv);
@@ -3783,7 +3784,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
                        /* get different child parameters from textures & vgroups */
                        memset(&ctx, 0, sizeof(ParticleThreadContext));
                        ctx.sim = *sim;
-                       ctx.dm = psmd->dm_final;
+                       ctx.mesh = psmd->mesh_final;
                        ctx.ma = ma;
                        /* TODO: assign vertex groups */
                        get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
@@ -4037,13 +4038,13 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part,
        bool is_grid = (part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT);
 
        if (cpa) {
-               if ((part->childtype == PART_CHILD_FACES) && (psmd->dm_final != NULL)) {
-                       CustomData *mtf_data = psmd->dm_final->getTessFaceDataLayout(psmd->dm_final);
+               if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != NULL)) {
+                       CustomData *mtf_data = &psmd->mesh_final->fdata;
                        const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE);
                        mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx);
 
                        if (mtface && !is_grid) {
-                               mface = psmd->dm_final->getTessFaceData(psmd->dm_final, cpa->num, CD_MFACE);
+                               mface = CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE);
                                mtface += cpa->num;
                                psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv);
                        }
@@ -4056,8 +4057,8 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part,
                }
        }
 
-       if ((part->from == PART_FROM_FACE) && (psmd->dm_final != NULL) && !is_grid) {
-               CustomData *mtf_data = psmd->dm_final->getTessFaceDataLayout(psmd->dm_final);
+       if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) {
+               CustomData *mtf_data = &psmd->mesh_final->fdata;
                const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE);
                mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx);
 
@@ -4066,14 +4067,14 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part,
                if (num == DMCACHE_NOTFOUND)
                        num = pa->num;
 
-               if (num >= psmd->dm_final->getNumTessFaces(psmd->dm_final)) {
+               if (num >= psmd->mesh_final->totface) {
                        /* happens when simplify is enabled
                         * gives invalid coords but would crash otherwise */
                        num = DMCACHE_NOTFOUND;
                }
 
                if (mtface && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
-                       mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE);
+                       mface = CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE);
                        mtface += num;
                        psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv);
                }
@@ -4249,7 +4250,7 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par
                float hairmat[4][4], imat[4][4];
 
                for (p = 0; p < psys->totpart; p++, pa++) {
-                       psys_mat_hair_to_global(sim.ob, sim.psmd->dm_final, psys->part->from, pa, hairmat);
+                       psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, psys->part->from, pa, hairmat);
                        invert_m4_m4(imat, hairmat);
 
                        hkey = pa->hair;
index bf21e18..e85a3f1 100644 (file)
@@ -50,9 +50,8 @@
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 
-#include "BKE_cdderivedmesh.h"
-#include "BKE_DerivedMesh.h"
 #include "BKE_global.h"
+#include "BKE_library.h"
 #include "BKE_mesh.h"
 #include "BKE_object.h"
 #include "BKE_particle.h"
@@ -80,7 +79,7 @@ static void alloc_child_particles(ParticleSystem *psys, int tot)
        }
 }
 
-static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, DerivedMesh *deformdm, ParticleSystem *psys, const bool use_render_params)
+static void distribute_simple_children(Scene *scene, Object *ob, Mesh *final_mesh, Mesh *deform_mesh, ParticleSystem *psys, const bool use_render_params)
 {
        ChildParticle *cpa = NULL;
        int i, p;
@@ -107,14 +106,14 @@ static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *fi
                }
        }
        /* dmcache must be updated for parent particles if children from faces is used */
-       psys_calc_dmcache(ob, finaldm, deformdm, psys);
+       psys_calc_dmcache(ob, final_mesh, deform_mesh, psys);
 }
-static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
+static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
 {
        ParticleData *pa=NULL;
        float min[3], max[3], delta[3], d;
-       MVert *mv, *mvert = dm->getVertDataArray(dm,0);
-       int totvert=dm->getNumVerts(dm), from=psys->part->from;
+       MVert *mv, *mvert = mesh->mvert;
+       int totvert=mesh->totvert, from=psys->part->from;
        int i, j, k, p, res=psys->part->grid_res, size[3], axis;
 
        /* find bounding box of dm */
@@ -196,8 +195,8 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
                int a, a1, a2, a0mul, a1mul, a2mul, totface;
                int amax= from==PART_FROM_FACE ? 3 : 1;
 
-               totface=dm->getNumTessFaces(dm);
-               mface=mface_array=dm->getTessFaceDataArray(dm,CD_MFACE);
+               totface = mesh->totface;
+               mface = mface_array = mesh->mface;
                
                for (a=0; a<amax; a++) {
                        if (a==0) { a0mul=res*res; a1mul=res; a2mul=1; }
@@ -440,7 +439,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i
        ParticleThreadContext *ctx= thread->ctx;
        MFace *mface;
 
-       mface = ctx->dm->getTessFaceDataArray(ctx->dm, CD_MFACE);
+       mface = ctx->mesh->mface;
 
        int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
 
@@ -449,12 +448,12 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i
 
        zero_v4(pa->fuv);
 
-       if (pa->num != DMCACHE_NOTFOUND && pa->num < ctx->dm->getNumVerts(ctx->dm)) {
+       if (pa->num != DMCACHE_NOTFOUND && pa->num < ctx->mesh->totvert) {
 
                /* This finds the first face to contain the emitting vertex,
                 * this is not ideal, but is mostly fine as UV seams generally
                 * map to equal-colored parts of a texture */
-               for (int i = 0; i < ctx->dm->getNumTessFaces(ctx->dm); i++, mface++) {
+               for (int i = 0; i < ctx->mesh->totface; i++, mface++) {
                        if (ELEM(pa->num, mface->v1, mface->v2, mface->v3, mface->v4)) {
                                unsigned int *vert = &mface->v1;
 
@@ -475,7 +474,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i
                KDTreeNearest ptn[3];
                int w, maxw;
                
-               psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
+               psys_particle_on_dm(ctx->mesh,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
                BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1);
                maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3);
                
@@ -491,7 +490,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i
 
 static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, int p) {
        ParticleThreadContext *ctx= thread->ctx;
-       DerivedMesh *dm= ctx->dm;
+       Mesh *mesh = ctx->mesh;
        float randu, randv;
        int distr= ctx->distr;
        int i;
@@ -500,7 +499,7 @@ static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, i
        MFace *mface;
        
        pa->num = i = ctx->index[p];
-       mface = dm->getTessFaceData(dm,i,CD_MFACE);
+       mface = &mesh->mface[i];
        
        switch (distr) {
                case PART_DISTR_JIT:
@@ -533,7 +532,7 @@ static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, i
 
 static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, int p) {
        ParticleThreadContext *ctx= thread->ctx;
-       DerivedMesh *dm= ctx->dm;
+       Mesh *mesh = ctx->mesh;
        float *v1, *v2, *v3, *v4, nor[3], co[3];
        float cur_d, min_d, randu, randv;
        int distr= ctx->distr;
@@ -541,10 +540,10 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
        int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
        
        MFace *mface;
-       MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
+       MVert *mvert = mesh->mvert;
        
        pa->num = i = ctx->index[p];
-       mface = dm->getTessFaceData(dm,i,CD_MFACE);
+       mface = &mesh->mface[i];
        
        switch (distr) {
                case PART_DISTR_JIT:
@@ -572,7 +571,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
        pa->foffset= 0.0f;
        
        /* experimental */
-       tot=dm->getNumTessFaces(dm);
+       tot = mesh->totface;
        
        psys_interpolate_face(mvert,mface,0,0,pa->fuv,co,nor,0,0,0);
        
@@ -582,7 +581,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
        min_d=FLT_MAX;
        intersect=0;
        
-       for (i=0,mface=dm->getTessFaceDataArray(dm,CD_MFACE); i<tot; i++,mface++) {
+       for (i=0, mface=mesh->mface; i<tot; i++,mface++) {
                if (i==pa->num) continue;
                
                v1=mvert[mface->v1].co;
@@ -628,7 +627,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
 static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, int p) {
        ParticleThreadContext *ctx= thread->ctx;
        Object *ob= ctx->sim.ob;
-       DerivedMesh *dm= ctx->dm;
+       Mesh *mesh = ctx->mesh;
        float orco1[3], co1[3], nor1[3];
        float randu, randv;
        int cfrom= ctx->cfrom;
@@ -644,7 +643,7 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i
                return;
        }
        
-       mf= dm->getTessFaceData(dm, ctx->index[p], CD_MFACE);
+       mf = &mesh->mface[ctx->index[p]];
        
        randu= BLI_rng_get_float(thread->rng);
        randv= BLI_rng_get_float(thread->rng);
@@ -661,7 +660,7 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i
                int parent[10];
                float pweight[10];
                
-               psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1);
+               psys_particle_on_dm(mesh,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1);
                BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1);
                maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3);
                
@@ -800,19 +799,18 @@ static void distribute_invalid(ParticleSimulationData *sim, int from)
        }
 }
 
-/* Creates a distribution of coordinates on a DerivedMesh */
-/* This is to denote functionality that does not yet work with mesh - only derived mesh */
+/* Creates a distribution of coordinates on a Mesh */
 static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, ParticleSimulationData *sim, int from)
 {
        Scene *scene = sim->scene;
-       DerivedMesh *finaldm = sim->psmd->dm_final;
+       Mesh *final_mesh = sim->psmd->mesh_final;
        Object *ob = sim->ob;
        ParticleSystem *psys= sim->psys;
        ParticleData *pa=0, *tpars= 0;
        ParticleSettings *part;
        ParticleSeam *seams= 0;
        KDTree *tree=0;
-       DerivedMesh *dm= NULL;
+       Mesh *mesh = NULL;
        float *jit= NULL;
        int i, p=0;
        int cfrom=0;
@@ -829,7 +827,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
        if (totpart==0)
                return 0;
        
-       if (!finaldm->deformedOnly && !finaldm->getTessFaceDataArray(finaldm, CD_ORIGINDEX)) {
+       if (!final_mesh->runtime.deformed_only && !CustomData_get_layer(&final_mesh->fdata, CD_ORIGINDEX)) {
                printf("Can't create particles with the current modifier stack, disable destructive modifiers\n");
 // XXX         error("Can't paint with the current modifier stack, disable destructive modifiers");
                return 0;
@@ -849,7 +847,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
                /* Simple children */
                if (part->childtype != PART_CHILD_FACES) {
                        BLI_srandom(31415926 + psys->seed + psys->child_seed);
-                       distribute_simple_children(scene, ob, finaldm, sim->psmd->dm_deformed, psys, use_render_params);
+                       distribute_simple_children(scene, ob, final_mesh, sim->psmd->mesh_deformed, psys, use_render_params);
                        return 0;
                }
        }
@@ -859,17 +857,23 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
                        BLI_srandom(31415926 + psys->seed);
 
                        if (psys->part->use_modifier_stack) {
-                               dm = finaldm;
+                               mesh = final_mesh;
                        }
                        else {
-                               dm = CDDM_from_mesh((Mesh*)ob->data);
+                               BKE_id_copy_ex(
+                                       NULL, ob->data, (ID **)&mesh,
+                                       LIB_ID_CREATE_NO_MAIN |
+                                       LIB_ID_CREATE_NO_USER_REFCOUNT |
+                                       LIB_ID_CREATE_NO_DEG_TAG |
+                                       LIB_ID_COPY_NO_PREVIEW,
+                                       false);
                        }
-                       DM_ensure_tessface(dm);
+                       BKE_mesh_tessface_ensure(mesh);
 
-                       distribute_grid(dm,psys);
+                       distribute_grid(mesh,psys);
 
-                       if (dm != finaldm) {
-                               dm->release(dm);
+                       if (mesh != final_mesh) {
+                               BKE_id_free(NULL, mesh);
                        }
 
                        return 0;
@@ -880,17 +884,17 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
        if (from == PART_FROM_CHILD) {
                distr=PART_DISTR_RAND;
                BLI_srandom(31415926 + psys->seed + psys->child_seed);
-               dm= finaldm;
+               mesh= final_mesh;
 
                /* BMESH ONLY */
-               DM_ensure_tessface(dm);
+               BKE_mesh_tessface_ensure(mesh);
 
                children=1;
 
                tree=BLI_kdtree_new(totpart);
 
                for (p=0,pa=psys->particles; p<totpart; p++,pa++) {
-                       psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco);
+                       psys_particle_on_dm(mesh,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco);
                        BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco, 1, 1);
                        BLI_kdtree_insert(tree, p, orco);
                }
@@ -905,20 +909,26 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
                BLI_srandom(31415926 + psys->seed);
                
                if (psys->part->use_modifier_stack)
-                       dm = finaldm;
+                       mesh = final_mesh;
                else
-                       dm= CDDM_from_mesh((Mesh*)ob->data);
+                       BKE_id_copy_ex(
+                                   NULL, ob->data, (ID **)&mesh,
+                                   LIB_ID_CREATE_NO_MAIN |
+                                   LIB_ID_CREATE_NO_USER_REFCOUNT |
+                                   LIB_ID_CREATE_NO_DEG_TAG |
+                                   LIB_ID_COPY_NO_PREVIEW,
+                                   false);
 
-               DM_ensure_tessface(dm);
+               BKE_mesh_tessface_ensure(mesh);
 
                /* we need orco for consistent distributions */
-               if (!CustomData_has_layer(&dm->vertData, CD_ORCO))
-                       DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob));
+               if (!CustomData_has_layer(&mesh->vdata, CD_ORCO))
+                       CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob), mesh->totvert);
 
                if (from == PART_FROM_VERT) {
-                       MVert *mv= dm->getVertDataArray(dm, CD_MVERT);
-                       float (*orcodata)[3] = dm->getVertDataArray(dm, CD_ORCO);
-                       int totvert = dm->getNumVerts(dm);
+                       MVert *mv = mesh->mvert;
+                       float (*orcodata)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO);
+                       int totvert = mesh->totvert;
 
                        tree=BLI_kdtree_new(totvert);
 
@@ -937,7 +947,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
        }
 
        /* Get total number of emission elements and allocate needed arrays */
-       totelem = (from == PART_FROM_VERT) ? dm->getNumVerts(dm) : dm->getNumTessFaces(dm);
+       totelem = (from == PART_FROM_VERT) ? mesh->totvert : mesh->totface;
 
        if (totelem == 0) {
                distribute_invalid(sim, children ? PART_FROM_CHILD : 0);
@@ -945,7 +955,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
                if (G.debug & G_DEBUG)
                        fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
 
-               if (dm != finaldm) dm->release(dm);
+               if (mesh != final_mesh) BKE_id_free(NULL, mesh);
 
                BLI_kdtree_free(tree);
 
@@ -962,10 +972,10 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
                float totarea=0.f, co1[3], co2[3], co3[3], co4[3];
                float (*orcodata)[3];
                
-               orcodata= dm->getVertDataArray(dm, CD_ORCO);
+               orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO);
 
                for (i=0; i<totelem; i++) {
-                       MFace *mf=dm->getTessFaceData(dm,i,CD_MFACE);
+                       MFace *mf = &mesh->mface[i];
 
                        if (orcodata) {
                                copy_v3_v3(co1, orcodata[mf->v1]);
@@ -980,14 +990,14 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
                                }
                        }
                        else {
-                               v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT);
-                               v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT);
-                               v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT);
+                               v1 = &mesh->mvert[mf->v1];
+                               v2 = &mesh->mvert[mf->v2];
+                               v3 = &mesh->mvert[mf->v3];
                                copy_v3_v3(co1, v1->co);
                                copy_v3_v3(co2, v2->co);
                                copy_v3_v3(co3, v3->co);
                                if (mf->v4) {
-                                       v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT);
+                                       v4 = &mesh->mvert[mf->v4];
                                        copy_v3_v3(co4, v4->co);
                                }
                        }
@@ -1014,7 +1024,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
        }
 
        /* Calculate weights from vgroup */
-       vweight = psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY);
+       vweight = psys_cache_vgroup(mesh,psys,PSYS_VG_DENSITY);
 
        if (vweight) {
                if (from==PART_FROM_VERT) {
@@ -1023,7 +1033,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
                }
                else { /* PART_FROM_FACE / PART_FROM_VOLUME */
                        for (i=0;i<totelem; i++) {
-                               MFace *mf=dm->getTessFaceData(dm,i,CD_MFACE);
+                               MFace *mf = &mesh->mface[i];
                                tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
                                
                                if (mf->v4) {
@@ -1126,12 +1136,12 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
                int *orig_index = NULL;
 
                if (from == PART_FROM_VERT) {
-                       if (dm->numVertData)
-                               orig_index = dm->getVertDataArray(dm, CD_ORIGINDEX);
+                       if (mesh->totvert)
+                               orig_index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX);
                }
                else {
-                       if (dm->numTessFaceData)
-                               orig_index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+                       if (mesh->totface)
+                               orig_index = CustomData_get_layer(&mesh->fdata, CD_ORIGINDEX);
                }
 
                if (orig_index) {
@@ -1174,7 +1184,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
        ctx->maxweight= maxweight;
        ctx->cfrom= cfrom;
        ctx->distr= distr;
-       ctx->dm= dm;
+       ctx->mesh= mesh;
        ctx->tpars= tpars;
 
        if (children) {
@@ -1198,7 +1208,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
        TaskPool *task_pool;
        ParticleThreadContext ctx;
        ParticleTask *tasks;
-       DerivedMesh *finaldm = sim->psmd->dm_final;
+       Mesh *final_mesh = sim->psmd->mesh_final;
        int i, totpart, numtasks;
        
        /* create a task pool for distribution tasks */
@@ -1223,10 +1233,10 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
        
        BLI_task_pool_free(task_pool);
        
-       psys_calc_dmcache(sim->ob, finaldm, sim->psmd->dm_deformed, sim->psys);
+       psys_calc_dmcache(sim->ob, final_mesh, sim->psmd->mesh_deformed, sim->psys);
        
-       if (ctx.dm != finaldm)
-               ctx.dm->release(ctx.dm);
+       if (ctx.mesh != final_mesh)
+               BKE_id_free(NULL, ctx.mesh);
        
        psys_tasks_free(tasks, numtasks);
        
@@ -1247,7 +1257,7 @@ void distribute_particles(ParticleSimulationData *sim, int from)
        int distr_error=0;
 
        if (psmd) {
-               if (psmd->dm_final)
+               if (psmd->mesh_final)
                        distribute_particles_on_dm(sim, from);
                else
                        distr_error=1;
index 6a9191b..ff61faf 100644 (file)
@@ -74,6 +74,7 @@
 #include "BKE_collision.h"
 #include "BKE_colortools.h"
 #include "BKE_effect.h"
+#include "BKE_library.h"
 #include "BKE_library_query.h"
 #include "BKE_particle.h"
 
@@ -310,7 +311,7 @@ int psys_get_tot_child(Scene *scene, ParticleSystem *psys, const bool use_render
 /*                     Distribution                                            */
 /************************************************/
 
-void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deformed, ParticleSystem *psys)
+void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_deformed, ParticleSystem *psys)
 {
        /* use for building derived mesh mapping info:
         *
@@ -323,13 +324,13 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform
        PARTICLE_P;
        
        /* CACHE LOCATIONS */
-       if (!dm_final->deformedOnly) {
+       if (!mesh_final->runtime.deformed_only) {
                /* Will use later to speed up subsurf/derivedmesh */
                LinkNode *node, *nodedmelem, **nodearray;
                int totdmelem, totelem, i, *origindex, *origindex_poly = NULL;
 
                if (psys->part->from == PART_FROM_VERT) {
-                       totdmelem= dm_final->getNumVerts(dm_final);
+                       totdmelem = mesh_final->totvert;
 
                        if (use_modifier_stack) {
                                totelem= totdmelem;
@@ -337,11 +338,11 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform
                        }
                        else {
                                totelem= me->totvert;
-                               origindex= dm_final->getVertDataArray(dm_final, CD_ORIGINDEX);
+                               origindex = CustomData_get_layer(&mesh_final->vdata, CD_ORIGINDEX);
                        }
                }
                else { /* FROM_FACE/FROM_VOLUME */
-                       totdmelem= dm_final->getNumTessFaces(dm_final);
+                       totdmelem= mesh_final->totface;
 
                        if (use_modifier_stack) {
                                totelem= totdmelem;
@@ -349,11 +350,11 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform
                                origindex_poly= NULL;
                        }
                        else {
-                               totelem = dm_deformed->getNumTessFaces(dm_deformed);
-                               origindex = dm_final->getTessFaceDataArray(dm_final, CD_ORIGINDEX);
+                               totelem = mesh_deformed->totface;
+                               origindex = CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX);
 
                                /* for face lookups we need the poly origindex too */
-                               origindex_poly= dm_final->getPolyDataArray(dm_final, CD_ORIGINDEX);
+                               origindex_poly = CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX);
                                if (origindex_poly == NULL) {
                                        origindex= NULL;
                                }
@@ -413,7 +414,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform
                                                pa->num_dmcache = DMCACHE_NOTFOUND;
                                }
                                else { /* FROM_FACE/FROM_VOLUME */
-                                       pa->num_dmcache = psys_particle_dm_face_lookup(dm_final, dm_deformed, pa->num, pa->fuv, nodearray);
+                                       pa->num_dmcache = psys_particle_dm_face_lookup(mesh_final, mesh_deformed, pa->num, pa->fuv, nodearray);
                                }
                        }
                }
@@ -437,7 +438,7 @@ void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData
 {
        memset(ctx, 0, sizeof(ParticleThreadContext));
        ctx->sim = *sim;
-       ctx->dm = ctx->sim.psmd->dm_final;
+       ctx->mesh = ctx->sim.psmd->mesh_final;
        ctx->ma = give_current_material(sim->ob, sim->psys->part->omat);
 }
 
@@ -3022,11 +3023,11 @@ static MDeformVert *hair_set_pinning(MDeformVert *dvert, float weight)
        return dvert;
 }
 
-static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int totedge, DerivedMesh **r_dm, ClothHairData **r_hairdata)
+static void hair_create_input_mesh(ParticleSimulationData *sim, int totpoint, int totedge, Mesh **r_mesh, ClothHairData **r_hairdata)
 {
        ParticleSystem *psys = sim->psys;
        ParticleSettings *part = psys->part;
-       DerivedMesh *dm;
+       Mesh *mesh;
        ClothHairData *hairdata;
        MVert *mvert;
        MEdge *medge;
@@ -3038,14 +3039,14 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int
        float max_length;
        float hair_radius;
        
-       dm = *r_dm;
-       if (!dm) {
-               *r_dm = dm = CDDM_new(totpoint, totedge, 0, 0, 0);
-               DM_add_vert_layer(dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
-       }
-       mvert = CDDM_get_verts(dm);
-       medge = CDDM_get_edges(dm);
-       dvert = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
+       mesh = *r_mesh;
+       if (!mesh) {
+               *r_mesh = mesh = BKE_mesh_new_nomain(totpoint, totedge, 0, 0, 0);
+               CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, mesh->totvert);
+       }
+       mvert = mesh->mvert;
+       medge = mesh->medge;
+       dvert = mesh->dvert;
        
        hairdata = *r_hairdata;
        if (!hairdata) {
@@ -3080,7 +3081,7 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int
                        pa->hair_index = hair_index;
                        use_hair = psys_hair_use_simulation(pa, max_length);
 
-                       psys_mat_hair_to_object(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat);
+                       psys_mat_hair_to_object(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat);
                        mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat);
                        normalize_m4(root_mat);
 
@@ -3177,26 +3178,26 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
        }
        
        realloc_roots = false; /* whether hair root info array has to be reallocated */
-       if (psys->hair_in_dm) {
-               DerivedMesh *dm = psys->hair_in_dm;
-               if (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm)) {
-                       dm->release(dm);
-                       psys->hair_in_dm = NULL;
+       if (psys->hair_in_mesh) {
+               Mesh *mesh = psys->hair_in_mesh;
+               if (totpoint != mesh->totvert || totedge != mesh->totedge) {
+                       BKE_id_free(NULL, mesh);
+                       psys->hair_in_mesh = NULL;
                        realloc_roots = true;
                }
        }
        
-       if (!psys->hair_in_dm || !psys->clmd->hairdata || realloc_roots) {
+       if (!psys->hair_in_mesh || !psys->clmd->hairdata || realloc_roots) {
                if (psys->clmd->hairdata) {
                        MEM_freeN(psys->clmd->hairdata);
                        psys->clmd->hairdata = NULL;
                }
        }
        
-       hair_create_input_dm(sim, totpoint, totedge, &psys->hair_in_dm, &psys->clmd->hairdata);
+       hair_create_input_mesh(sim, totpoint, totedge, &psys->hair_in_mesh, &psys->clmd->hairdata);
        
-       if (psys->hair_out_dm)
-               psys->hair_out_dm->release(psys->hair_out_dm);
+       if (psys->hair_out_mesh)
+               BKE_id_free(NULL, psys->hair_out_mesh);
        
        psys->clmd->point_cache = psys->pointcache;
        /* for hair sim we replace the internal cloth effector weights temporarily
@@ -3205,13 +3206,22 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
        clmd_effweights = psys->clmd->sim_parms->effector_weights;
        psys->clmd->sim_parms->effector_weights = psys->part->effector_weights;
        
-       deformedVerts = MEM_mallocN(sizeof(*deformedVerts) * psys->hair_in_dm->getNumVerts(psys->hair_in_dm), "do_hair_dynamics vertexCos");
-       psys->hair_out_dm = CDDM_copy(psys->hair_in_dm);
-       psys->hair_out_dm->getVertCos(psys->hair_out_dm, deformedVerts);
-       
-       clothModifier_do(psys->clmd, sim->depsgraph, sim->scene, sim->ob, psys->hair_in_dm, deformedVerts);
-       
-       CDDM_apply_vert_coords(psys->hair_out_dm, deformedVerts);
+       BKE_id_copy_ex(
+                   NULL, &psys->hair_in_mesh->id, (ID **)&psys->hair_out_mesh,
+                   LIB_ID_CREATE_NO_MAIN |
+                   LIB_ID_CREATE_NO_USER_REFCOUNT |
+                   LIB_ID_CREATE_NO_DEG_TAG |
+                   LIB_ID_COPY_NO_PREVIEW,
+                   false);
+       deformedVerts = BKE_mesh_vertexCos_get(psys->hair_out_mesh, NULL);
+
+       /* TODO(Sybren): after porting Cloth modifier, remove this conversion */
+       DerivedMesh *hair_in_dm = CDDM_from_mesh(psys->hair_in_mesh);
+       clothModifier_do(psys->clmd, sim->depsgraph, sim->scene, sim->ob, hair_in_dm, deformedVerts);
+       hair_in_dm->needsFree = 1;
+       hair_in_dm->release(hair_in_dm);
+
+       BKE_mesh_apply_vert_coords(psys->hair_out_mesh, deformedVerts);
        
        MEM_freeN(deformedVerts);
        
@@ -3238,7 +3248,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re
 
        if (psys->recalc & PSYS_RECALC_RESET) {
                /* need this for changing subsurf levels */
-               psys_calc_dmcache(sim->ob, sim->psmd->dm_final, sim->psmd->dm_deformed, psys);
+               psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_deformed, psys);
 
                if (psys->clmd)
                        cloth_free_modifier(psys->clmd);
@@ -3285,7 +3295,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
 
                if (pa->totkey) {
                        sub_v3_v3(key->co, root->co);
-                       psys_vec_rot_to_face(sim->psmd->dm_final, pa, key->co);
+                       psys_vec_rot_to_face(sim->psmd->mesh_final, pa, key->co);
                }
 
                key->time = pa->state.time;
@@ -4237,11 +4247,11 @@ void particle_system_update(struct Depsgraph *depsgraph, Scene *scene, Object *o
                        return;
        }
 
-       if (!sim.psmd->dm_final)
+       if (!sim.psmd->mesh_final)
                return;
 
        if (part->from != PART_FROM_VERT) {
-               DM_ensure_tessface(sim.psmd->dm_final);
+               BKE_mesh_tessface_ensure(sim.psmd->mesh_final);
        }
 
        /* execute drivers only, as animation has already been done */
index 6c617b5..9c020a8 100644 (file)
@@ -4464,7 +4464,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                                        psys->clmd->sim_parms->presets = 0;
                        }
                        
-                       psys->hair_in_dm = psys->hair_out_dm = NULL;
+                       psys->hair_in_mesh = psys->hair_out_mesh = NULL;
                        psys->clmd->solver_result = NULL;
                }
 
@@ -5221,8 +5221,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                else if (md->type == eModifierType_ParticleSystem) {
                        ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
                        
-                       psmd->dm_final = NULL;
-                       psmd->dm_deformed = NULL;
+                       psmd->mesh_final = NULL;
+                       psmd->mesh_deformed = NULL;
                        psmd->psys= newdataadr(fd, psmd->psys);
                        psmd->flag &= ~eParticleSystemFlag_psys_updated;
                        psmd->flag |= eParticleSystemFlag_file_loaded;
index b8b24ac..c6cc243 100644 (file)
 #include "BLI_string.h"
 #include "BLI_ghash.h"
 
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_particle_types.h"
 
-#include "BKE_DerivedMesh.h"
+#include "BKE_mesh.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 
@@ -253,12 +255,12 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys,
        ParticleData *particle = &psys->particles[parent_index];
        int num = particle->num_dmcache;
        if (num == DMCACHE_NOTFOUND) {
-               if (particle->num < psmd->dm_final->getNumTessFaces(psmd->dm_final)) {
+               if (particle->num < psmd->mesh_final->totface) {
                        num = particle->num;
                }
        }
        if (num != DMCACHE_NOTFOUND) {
-               MFace *mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE);
+               MFace *mface = &psmd->mesh_final->mface[num];
                for (int j = 0; j < num_uv_layers; j++) {
                        psys_interpolate_uvs(mtfaces[j] + num,
                                             mface->v4,
@@ -286,8 +288,7 @@ static void particle_interpolate_children_uvs(ParticleSystem *psys,
        ChildParticle *particle = &psys->child[child_index];
        int num = particle->num;
        if (num != DMCACHE_NOTFOUND) {
-               MFace *mface = psmd->dm_final->getTessFaceData(
-                       psmd->dm_final, num, CD_MFACE);
+               MFace *mface = &psmd->mesh_final->mface[num];
                for (int j = 0; j < num_uv_layers; j++) {
                        psys_interpolate_uvs(
                                mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]);
@@ -456,8 +457,8 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
        float (**parent_uvs)[2] = NULL;
 
        if (psmd != NULL) {
-               if (CustomData_has_layer(&psmd->dm_final->loopData, CD_MLOOPUV)) {
-                       num_uv_layers = CustomData_number_of_layers(&psmd->dm_final->loopData, CD_MLOOPUV);
+               if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) {
+                       num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV);
                }
        }
 
@@ -472,7 +473,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
                uv_id = MEM_mallocN(sizeof(*uv_id) * num_uv_layers, "UV attrib format");
 
                for (int i = 0; i < num_uv_layers; i++) {
-                       const char *name = CustomData_get_layer_name(&psmd->dm_final->loopData, CD_MLOOPUV, i);
+                       const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i);
                        char uuid[32];
 
                        BLI_snprintf(uuid, sizeof(uuid), "u%u", BLI_ghashutil_strhash_p(name));
@@ -490,10 +491,10 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
                             true);
 
        if (num_uv_layers) {
-               DM_ensure_tessface(psmd->dm_final);
+               BKE_mesh_tessface_ensure(psmd->mesh_final);
                mtfaces = MEM_mallocN(sizeof(*mtfaces) * num_uv_layers, "Faces UV layers");
                for (int i = 0; i < num_uv_layers; i++) {
-                       mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->dm_final->faceData, CD_MTFACE, i);
+                       mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MTFACE, i);
                }
        }
 
index 787cf7f..dfa5a51 100644 (file)
@@ -226,9 +226,14 @@ typedef struct MirrTopoStore_t {
 
 bool ED_mesh_mirrtopo_recalc_check(
         struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store);
+bool ED_mesh_mirrtopo_recalc_check__real_mesh(
+        struct Mesh *me, struct Mesh *dm, MirrTopoStore_t *mesh_topo_store);
 void ED_mesh_mirrtopo_init(
         struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store,
         const bool skip_em_vert_array_init);
+void ED_mesh_mirrtopo_init__real_mesh(
+        struct Mesh *me, struct Mesh *dm, MirrTopoStore_t *mesh_topo_store,
+        const bool skip_em_vert_array_init);
 void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store);
 
 
@@ -318,16 +323,21 @@ int         join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op);
 /* mirror lookup api */
 int ED_mesh_mirror_spatial_table(
         struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, const float co[3], char mode);
+int ED_mesh_mirror_spatial_table__real_mesh(
+        struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh, const float co[3], char mode);
 int  ED_mesh_mirror_topo_table(struct Object *ob, struct DerivedMesh *dm, char mode);
+int ED_mesh_mirror_topo_table__real_mesh(struct Object *ob, struct Mesh *mesh, char mode);
 
 /* retrieves mirrored cache vert, or NULL if there isn't one.
  * note: calling this without ensuring the mirror cache state
  * is bad.*/
 int            mesh_get_x_mirror_vert(struct Object *ob, struct DerivedMesh *dm, int index, const bool use_topology);
+int mesh_get_x_mirror_vert__real_mesh(struct Object *ob, struct Mesh *mesh, int index, const bool use_topology);
 struct BMVert *editbmesh_get_x_mirror_vert(struct Object *ob, struct BMEditMesh *em,
                                            struct BMVert *eve, const float co[3],
                                            int index, const bool use_topology);
 int           *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm);
+int *mesh_get_x_mirror_faces__real_mesh(struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh);
 
 int ED_mesh_mirror_get_vert(struct Object *ob, int index);
 
index e8f3e59..ab44e01 100644 (file)
@@ -1030,7 +1030,7 @@ void EDBM_verts_mirror_cache_begin_ex(
        BM_mesh_elem_index_ensure(bm, BM_VERT);
 
        if (use_topology) {
-               ED_mesh_mirrtopo_init(me, NULL, &mesh_topo_store, true);
+               ED_mesh_mirrtopo_init__real_mesh(me, NULL, &mesh_topo_store, true);
        }
        else {
                tree = BLI_kdtree_new(bm->totvert);
index 22bfd8e..4c078d2 100644 (file)
@@ -37,6 +37,8 @@
 #include "BKE_DerivedMesh.h"
 #include "BLI_kdtree.h"
 #include "BKE_editmesh.h"
+#include "BKE_library.h"
+#include "BKE_mesh.h"
 
 #include "ED_mesh.h"
 
@@ -93,7 +95,73 @@ int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, DerivedMesh *dm, co
                else {
                        MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert;
                        int i;
-                       
+
+                       for (i = 0; i < totvert; i++, mvert++) {
+                               BLI_kdtree_insert(MirrKdStore.tree, i, mvert->co);
+                       }
+               }
+
+               BLI_kdtree_balance(MirrKdStore.tree);
+       }
+       else if (mode == 'e') { /* end table */
+               if (MirrKdStore.tree) {
+                       BLI_kdtree_free(MirrKdStore.tree);
+                       MirrKdStore.tree = NULL;
+               }
+       }
+       else {
+               BLI_assert(0);
+       }
+
+       return 0;
+}
+
+/* mode is 's' start, or 'e' end, or 'u' use */
+/* if end, ob can be NULL */
+int ED_mesh_mirror_spatial_table__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, const float co[3], char mode)
+{
+       if (mode == 'u') {        /* use table */
+               if (MirrKdStore.tree == NULL)
+                       ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 's');
+
+               if (MirrKdStore.tree) {
+                       KDTreeNearest nearest;
+                       const int i = BLI_kdtree_find_nearest(MirrKdStore.tree, co, &nearest);
+
+                       if (i != -1) {
+                               if (nearest.dist < KD_THRESH) {
+                                       return i;
+                               }
+                       }
+               }
+               return -1;
+       }
+       else if (mode == 's') {   /* start table */
+               Mesh *me = ob->data;
+               const bool use_em = (!mesh && em && me->edit_btmesh == em);
+               const int totvert = use_em ? em->bm->totvert : mesh ? mesh->totvert : me->totvert;
+
+               if (MirrKdStore.tree) /* happens when entering this call without ending it */
+                       ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, co, 'e');
+
+               MirrKdStore.tree = BLI_kdtree_new(totvert);
+
+               if (use_em) {
+                       BMVert *eve;
+                       BMIter iter;
+                       int i;
+
+                       /* this needs to be valid for index lookups later (callers need) */
+                       BM_mesh_elem_table_ensure(em->bm, BM_VERT);
+
+                       BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+                               BLI_kdtree_insert(MirrKdStore.tree, i, eve->co);
+                       }
+               }
+               else {
+                       MVert *mvert = mesh ? mesh->mvert : me->mvert;
+                       int i;
+
                        for (i = 0; i < totvert; i++, mvert++) {
                                BLI_kdtree_insert(MirrKdStore.tree, i, mvert->co);
                        }
@@ -172,10 +240,61 @@ bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, MirrTopoStore_t *m
        }
 
 }
+bool ED_mesh_mirrtopo_recalc_check__real_mesh(Mesh *me, Mesh *dm, MirrTopoStore_t *mesh_topo_store)
+{
+       const bool is_editmode = (me->edit_btmesh != NULL);
+       int totvert;
+       int totedge;
+
+       if (dm) {
+               totvert = dm->totvert;
+               totedge = dm->totedge;
+       }
+       else if (me->edit_btmesh) {
+               totvert = me->edit_btmesh->bm->totvert;
+               totedge = me->edit_btmesh->bm->totedge;
+       }
+       else {
+               totvert = me->totvert;
+               totedge = me->totedge;
+       }
+
+       if ((mesh_topo_store->index_lookup == NULL) ||
+           (mesh_topo_store->prev_is_editmode != is_editmode) ||
+           (totvert != mesh_topo_store->prev_vert_tot) ||
+           (totedge != mesh_topo_store->prev_edge_tot))
+       {
+               return true;
+       }
+       else {
+               return false;
+       }
+
+}
+
 
 void ED_mesh_mirrtopo_init(
         Mesh *me, DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store,
         const bool skip_em_vert_array_init)
+{
+       Mesh *fake_mesh = NULL;
+
+       if (dm != NULL) {
+               /* ED_real_mesh_mirrtopo_init() only uses the counts, not the actual data */
+               fake_mesh = BKE_mesh_new_nomain(dm->getNumVerts(dm), dm->getNumEdges(dm), dm->getNumTessFaces(dm),
+                                               dm->getNumLoops(dm), dm->getNumPolys(dm));
+       }
+
+       ED_mesh_mirrtopo_init__real_mesh(me, fake_mesh, mesh_topo_store, skip_em_vert_array_init);
+
+       if (dm != NULL) {
+               BKE_id_free(NULL, fake_mesh);
+       }
+}
+
+void ED_mesh_mirrtopo_init__real_mesh(
+        Mesh *me, Mesh *dm, MirrTopoStore_t *mesh_topo_store,
+        const bool skip_em_vert_array_init)
 {
        const bool is_editmode = (me->edit_btmesh != NULL);
        MEdge *medge = NULL, *med;
@@ -208,7 +327,7 @@ void ED_mesh_mirrtopo_init(
                totvert = em->bm->totvert;
        }
        else {
-               totvert = dm ? dm->getNumVerts(dm) : me->totvert;
+               totvert = dm ? dm->totvert : me->totvert;
        }
 
        topo_hash = MEM_callocN(totvert * sizeof(MirrTopoHash_t), "TopoMirr");
@@ -224,8 +343,8 @@ void ED_mesh_mirrtopo_init(
                }
        }
        else {
-               totedge = dm ? dm->getNumEdges(dm) : me->totedge;
-               medge = dm ? dm->getEdgeArray(dm) : me->medge;
+               totedge = dm ? dm->totedge : me->totedge;
+               medge = dm ? dm->medge : me->medge;
 
                for (a = 0, med = medge; a < totedge; a++, med++) {
                        const unsigned int i1 = med->v1, i2 = med->v2;
index 8345812..9b86f90 100644 (file)
@@ -707,6 +707,30 @@ int ED_mesh_mirror_topo_table(
        return 0;
 }
 
+/* mode is 's' start, or 'e' end, or 'u' use */
+/* if end, ob can be NULL */
+/* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */
+int ED_mesh_mirror_topo_table__real_mesh(
+        Object *ob, Mesh *mesh, char mode)
+{
+       if (mode == 'u') {        /* use table */
+               if (ED_mesh_mirrtopo_recalc_check__real_mesh(ob->data, mesh, &mesh_topo_store)) {
+                       ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 's');
+               }
+       }
+       else if (mode == 's') { /* start table */
+               ED_mesh_mirrtopo_init__real_mesh(ob->data, mesh, &mesh_topo_store, false);
+       }
+       else if (mode == 'e') { /* end table */
+               ED_mesh_mirrtopo_free(&mesh_topo_store);
+       }
+       else {
+               BLI_assert(0);
+       }
+
+       return 0;
+}
+
 /** \} */
 
 
@@ -742,6 +766,38 @@ int mesh_get_x_mirror_vert(Object *ob, DerivedMesh *dm, int index, const bool us
        }
 }
 
+static int mesh_get_x_mirror_vert_spatial__real_mesh(Object *ob, Mesh *mesh, int index)
+{
+       Mesh *me = ob->data;
+       MVert *mvert = mesh ? mesh->mvert : me->mvert;
+       float vec[3];
+
+       mvert = &mvert[index];
+       vec[0] = -mvert->co[0];
+       vec[1] = mvert->co[1];
+       vec[2] = mvert->co[2];
+
+       return ED_mesh_mirror_spatial_table__real_mesh(ob, NULL, mesh, vec, 'u');
+}
+
+static int mesh_get_x_mirror_vert_topo__real_mesh(Object *ob, Mesh *mesh, int index)
+{
+       if (ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 'u') == -1)
+               return -1;
+
+       return mesh_topo_store.index_lookup[index];
+}
+
+int mesh_get_x_mirror_vert__real_mesh(Object *ob, Mesh *mesh, int index, const bool use_topology)
+{
+       if (use_topology) {
+               return mesh_get_x_mirror_vert_topo__real_mesh(ob, mesh, index);
+       }
+       else {
+               return mesh_get_x_mirror_vert_spatial__real_mesh(ob, mesh, index);
+       }
+}
+
 static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, const float co[3])
 {
        float vec[3];
@@ -991,7 +1047,67 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, DerivedMesh *dm)
 
        BLI_ghash_free(fhash, NULL, NULL);
        MEM_freeN(mirrorverts);
-       
+
+       return mirrorfaces;
+}
+
+/* This is a Mesh-based copy of mesh_get_x_mirror_faces() */
+int *mesh_get_x_mirror_faces__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh)
+{
+       Mesh *me = ob->data;
+       MVert *mv, *mvert;
+       MFace mirrormf, *mf, *hashmf, *mface;
+       GHash *fhash;
+       int *mirrorverts, *mirrorfaces;
+
+       BLI_assert(em == NULL);  /* Does not work otherwise, currently... */
+
+       const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
+       const int totvert = mesh ? mesh->totvert : me->totvert;
+       const int totface = mesh ? mesh->totface : me->totface;
+       int a;
+
+       mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts");
+       mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces");
+
+       mvert = mesh ? mesh->mvert : me->mvert;
+       mface = mesh ? mesh->mface : me->mface;
+
+       ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 's');
+
+       for (a = 0, mv = mvert; a < totvert; a++, mv++)
+               mirrorverts[a] = mesh_get_x_mirror_vert__real_mesh(ob, mesh, a, use_topology);
+
+       ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 'e');
+
+       fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface);
+       for (a = 0, mf = mface; a < totface; a++, mf++)
+               BLI_ghash_insert(fhash, mf, mf);
+
+       for (a = 0, mf = mface; a < totface; a++, mf++) {
+               mirrormf.v1 = mirrorverts[mf->v3];
+               mirrormf.v2 = mirrorverts[mf->v2];
+               mirrormf.v3 = mirrorverts[mf->v1];
+               mirrormf.v4 = (mf->v4) ? mirrorverts[mf->v4] : 0;
+
+               /* make sure v4 is not 0 if a quad */
+               if (mf->v4 && mirrormf.v4 == 0) {
+                       SWAP(unsigned int, mirrormf.v1, mirrormf.v3);
+                       SWAP(unsigned int, mirrormf.v2, mirrormf.v4);
+               }
+
+               hashmf = BLI_ghash_lookup(fhash, &mirrormf);
+               if (hashmf) {
+                       mirrorfaces[a * 2] = hashmf - mface;
+                       mirrorfaces[a * 2 + 1] = mirror_facerotation(&mirrormf, hashmf);
+               }
+               else
+                       mirrorfaces[a * 2] = -1;
+       }
+
+       BLI_ghash_free(fhash, NULL, NULL);
+       MEM_freeN(mirrorverts);
+
        return mirrorfaces;
 }
 
index 3df934a..164001b 100644 (file)
@@ -55,6 +55,7 @@
 #include "BKE_DerivedMesh.h"
 #include "BKE_global.h"
 #include "BKE_object.h"
+#include "BKE_library.h"
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_particle.h"
@@ -364,7 +365,7 @@ typedef struct PEData {
        Scene *scene;
        ViewLayer *view_layer;
        Object *ob;
-       DerivedMesh *dm;
+       Mesh *mesh;
        PTCacheEdit *edit;
        BVHTreeFromMesh shape_bvh;
        Depsgraph *depsgraph;
@@ -426,15 +427,15 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
 
 static bool PE_create_shape_tree(PEData *data, Object *shapeob)
 {
-       DerivedMesh *dm = shapeob->derivedFinal;
+       Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_object(shapeob, 0);
        
        memset(&data->shape_bvh, 0, sizeof(data->shape_bvh));
        
-       if (!dm) {
+       if (!mesh) {
                return false;
        }
        
-       return (bvhtree_from_mesh_get(&data->shape_bvh, dm, BVHTREE_FROM_LOOPTRI, 4) != NULL);
+       return (BKE_bvhtree_from_mesh_get(&data->shape_bvh, mesh, BVHTREE_FROM_LOOPTRI, 4) != NULL);
 }
 
 static void PE_free_shape_tree(PEData *data)
@@ -667,7 +668,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
                                if (selected==0 || key->flag & PEK_SELECT) {
                                        if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
                                                if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
-                                                       psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat);
+                                                       psys_mat_hair_to_global(data->ob, psmd->mesh_final, psys->part->from, psys->particles + p, mat);
                                                        invert_m4_m4(imat, mat);
                                                }
 
@@ -682,7 +683,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
                                if (selected==0 || key->flag & PEK_SELECT) {
                                        if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
                                                if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
-                                                       psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat);
+                                                       psys_mat_hair_to_global(data->ob, psmd->mesh_final, psys->part->from, psys->particles + p, mat);
                                                        invert_m4_m4(imat, mat);
                                                }
 
@@ -769,7 +770,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
        psmd= psys_get_modifier(ob, psys);
        totpart= psys->totpart;
 
-       if (!psmd->dm_final)
+       if (!psmd->mesh_final)
                return;
 
        tree= BLI_kdtree_new(totpart);
@@ -777,7 +778,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
        /* insert particles into kd tree */
        LOOP_PARTICLES {
                key = pa->hair;
-               psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat);
+               psys_mat_hair_to_orco(ob, psmd->mesh_final, psys->part->from, pa, mat);
                copy_v3_v3(co, key->co);
                mul_m4_v3(mat, co);
                BLI_kdtree_insert(tree, p, co);
@@ -791,7 +792,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
        
        LOOP_PARTICLES {
                key = pa->hair;
-               psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat);
+               psys_mat_hair_to_orco(ob, psmd->mesh_final, psys->part->from, pa, mat);
                copy_v3_v3(co, key->co);
                mul_m4_v3(mat, co);
                co[0] = -co[0];
@@ -817,7 +818,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
        BLI_kdtree_free(tree);
 }
 
-static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa)
+static void PE_mirror_particle(Object *ob, Mesh *mesh, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa)
 {
        HairKey *hkey, *mhkey;
        PTCacheEditPoint *point, *mpoint;
@@ -868,8 +869,8 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys
        }
 
        /* mirror positions and tags */
-       psys_mat_hair_to_orco(ob, dm, psys->part->from, pa, mat);
-       psys_mat_hair_to_orco(ob, dm, psys->part->from, mpa, mmat);
+       psys_mat_hair_to_orco(ob, mesh, psys->part->from, pa, mat);
+       psys_mat_hair_to_orco(ob, mesh, psys->part->from, mpa, mmat);
        invert_m4_m4(immat, mmat);
 
        hkey=pa->hair;
@@ -906,7 +907,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
        edit= psys->edit;
        psmd= psys_get_modifier(ob, psys);
 
-       if (!psmd->dm_final)
+       if (!psmd->mesh_final)
                return;
 
        if (!edit->mirror_cache)
@@ -919,7 +920,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
         * to avoid doing mirror twice */
        LOOP_POINTS {
                if (point->flag & PEP_EDIT_RECALC) {
-                       PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL);
+                       PE_mirror_particle(ob, psmd->mesh_final, psys, psys->particles + p, NULL);
 
                        if (edit->mirror_cache[p] != -1)
                                edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC;
@@ -954,11 +955,11 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
        psys = edit->psys;
        psmd = psys_get_modifier(ob, psys);
 
-       if (!psmd->dm_final)
+       if (!psmd->mesh_final)
                return;
 
        LOOP_EDITED_POINTS {
-               psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles + p, hairmat);
+               psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles + p, hairmat);
        
                LOOP_KEYS {
                        mul_m4_v3(hairmat, key->co);
@@ -1105,12 +1106,12 @@ void recalc_emitter_field(Depsgraph *depsgraph, Object *ob, ParticleSystem *psys
 {
        Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
        ParticleSystem *psys_eval = psys_eval_get(depsgraph, ob, psys);
-       DerivedMesh *dm = psys_get_modifier(object_eval, psys_eval)->dm_final;
+       Mesh *mesh = psys_get_modifier(object_eval, psys_eval)->mesh_final;
        PTCacheEdit *edit = psys->edit;
        float *vec, *nor;
        int i, totface /*, totvert*/;
 
-       if (!dm)
+       if (!mesh)
                return;
 
        if (edit->emitter_cosnos)
@@ -1118,7 +1119,7 @@ void recalc_emitter_field(Depsgraph *depsgraph, Object *ob, ParticleSystem *psys
 
        BLI_kdtree_free(edit->emitter_field);
 
-       totface=dm->getNumTessFaces(dm);
+       totface = mesh->totface;
        /*totvert=dm->getNumVerts(dm);*/ /*UNSUED*/
 
        edit->emitter_cosnos=MEM_callocN(totface*6*sizeof(float), "emitter cosnos");
@@ -1129,23 +1130,23 @@ void recalc_emitter_field(Depsgraph *depsgraph, Object *ob, ParticleSystem *psys
        nor=vec+3;
 
        for (i=0; i<totface; i++, vec+=6, nor+=6) {
-               MFace *mface=dm->getTessFaceData(dm, i, CD_MFACE);
+               MFace *mface = &mesh->mface[i];
                MVert *mvert;
 
-               mvert=dm->getVertData(dm, mface->v1, CD_MVERT);
+               mvert = &mesh->mvert[mface->v1];
                copy_v3_v3(vec, mvert->co);
                VECCOPY(nor, mvert->no);
 
-               mvert=dm->getVertData(dm, mface->v2, CD_MVERT);
+               mvert = &mesh->mvert[mface->v2];
                add_v3_v3v3(vec, vec, mvert->co);
                VECADD(nor, nor, mvert->no);
 
-               mvert=dm->getVertData(dm, mface->v3, CD_MVERT);
+               mvert = &mesh->mvert[mface->v3];
                add_v3_v3v3(vec, vec, mvert->co);
                VECADD(nor, nor, mvert->no);
 
                if (mface->v4) {
-                       mvert=dm->getVertData(dm, mface->v4, CD_MVERT);
+                       mvert = &mesh->mvert[mface->v4];
                        add_v3_v3v3(vec, vec, mvert->co);
                        VECADD(nor, nor, mvert->no);
                        
@@ -1208,12 +1209,12 @@ void update_world_cos(Depsgraph *depsgraph, Object *ob, PTCacheEdit *edit)
                psys_eval = psmd_eval->psys;
        }
 
-       if (psys == 0 || psys->edit == 0 || psmd_eval->dm_final == NULL)
+       if (psys == 0 || psys->edit == 0 || psmd_eval->mesh_final == NULL)
                return;
 
        LOOP_POINTS {
                if (!(psys->flag & PSYS_GLOBAL_HAIR))
-                       psys_mat_hair_to_global(ob_eval, psmd_eval->dm_final, psys->part->from, psys_eval->particles+p, hairmat);
+                       psys_mat_hair_to_global(ob_eval, psmd_eval->mesh_final, psys->part->from, psys_eval->particles+p, hairmat);
 
                LOOP_KEYS {
                        copy_v3_v3(key->world_co, key->co);
@@ -1860,7 +1861,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
 
        LOOP_VISIBLE_POINTS {
                if (edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR))
-                       psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + p, mat);
+                       psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles + p, mat);
 
                if (pset->selectmode==SCE_SELECT_POINT) {
                        LOOP_KEYS {
@@ -2305,7 +2306,7 @@ static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror)
                psmd= psys_get_modifier(ob, psys);
 
                LOOP_TAGGED_POINTS {
-                       PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL);
+                       PE_mirror_particle(ob, psmd->mesh_final, psys, psys->particles + p, NULL);
                }
        }
 
@@ -2385,7 +2386,7 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys)
 
                LOOP_POINTS {
                        LOOP_TAGGED_KEYS {
-                               PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL);
+                               PE_mirror_particle(ob, psmd->mesh_final, psys, psys->particles + p, NULL);
                                break;
                        }
                }
@@ -2600,7 +2601,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
                        
                /* insert particles into kd tree */
                LOOP_SELECTED_POINTS {
-                       psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat);
+                       psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat);
                        copy_v3_v3(co, point->keys->co);
                        mul_m4_v3(mat, co);
                        BLI_kdtree_insert(tree, p, co);
@@ -2610,7 +2611,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
 
                /* tag particles to be removed */
                LOOP_SELECTED_POINTS {
-                       psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat);
+                       psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat);
                        copy_v3_v3(co, point->keys->co);
                        mul_m4_v3(mat, co);
 
@@ -2845,17 +2846,17 @@ static void PE_mirror_x(
                return;
 
        psmd= psys_get_modifier(ob, psys);
-       if (!psmd->dm_final)
+       if (!psmd->mesh_final)
                return;
 
-       const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly);
+       const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd->mesh_final->runtime.deformed_only);
 
        /* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */
        BKE_mesh_tessface_ensure(me);
 
-       /* Note: In case psys uses DM tessface indices, we mirror final DM itself, not orig mesh. Avoids an (impossible)
-        *       dm -> orig -> dm tessface indices conversion... */
-       mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? psmd->dm_final : NULL);
+       /* Note: In case psys uses Mesh tessface indices, we mirror final Mesh itself, not orig mesh. Avoids an (impossible)
+        *       mesh -> orig -> mesh tessface indices conversion... */
+       mirrorfaces = mesh_get_x_mirror_faces__real_mesh(ob, NULL, use_dm_final_indices ? psmd->mesh_final : NULL);
 
        if (!edit->mirror_cache)
                PE_update_mirror_cache(ob, psys);
@@ -2869,7 +2870,7 @@ static void PE_mirror_x(
                        if (point_is_selected(point)) {
                                if (edit->mirror_cache[p] != -1) {
                                        /* already has a mirror, don't need to duplicate */
-                                       PE_mirror_particle(ob, psmd->dm_final, psys, pa, NULL);
+                                       PE_mirror_particle(ob, psmd->mesh_final, psys, pa, NULL);
                                        continue;
                                }
                                else
@@ -2882,7 +2883,7 @@ static void PE_mirror_x(
        }
 
        if (newtotpart != psys->totpart) {
-               MFace *mtessface = use_dm_final_indices ? psmd->dm_final->getTessFaceArray(psmd->dm_final) : me->mface;
+               MFace *mtessface = use_dm_final_indices ? psmd->mesh_final->mface : me->mface;
 
                /* allocate new arrays and copy existing */
                new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new");
@@ -2951,7 +2952,7 @@ static void PE_mirror_x(
                        }
                        else {
                                newpa->num_dmcache = psys_particle_dm_face_lookup(
-                                                        psmd->dm_final, psmd->dm_deformed, newpa->num, newpa->fuv, NULL);
+                                                        psmd->mesh_final, psmd->mesh_deformed, newpa->num, newpa->fuv, NULL);
                        }
 
                        /* update edit key pointers */
@@ -2962,7 +2963,7 @@ static void PE_mirror_x(
                        }
 
                        /* map key positions as mirror over x axis */
-                       PE_mirror_particle(ob, psmd->dm_final, psys, pa, newpa);
+                       PE_mirror_particle(ob, psmd->mesh_final, psys, pa, newpa);
 
                        newpa++;
                        newpoint++;
@@ -3172,7 +3173,7 @@ static void brush_puff(PEData *data, int point_index)
        }
 
        if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
-               psys_mat_hair_to_global(data->ob, data->dm, psys->part->from, psys->particles + point_index, mat);
+               psys_mat_hair_to_global(data->ob, data->mesh, psys->part->from, psys->particles + point_index, mat);
                invert_m4_m4(imat, mat);
        }
        else {
@@ -3367,7 +3368,7 @@ static void intersect_dm_quad_weights(const float v1[3], const float v2[3], cons
 }
 
 /* check intersection with a derivedmesh */
-static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, DerivedMesh *dm,
+static int particle_intersect_mesh(const bContext *C, Scene *scene, Object *ob, Mesh *mesh,
                                  float *vert_cos,
                                  const float co1[3], const float co2[3],
                                  float *min_d, int *min_face, float *min_w,
@@ -3381,10 +3382,11 @@ static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, De
        float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3], p_max[3];
        float cur_ipoint[3];
        
-       if (dm == NULL) {
+       if (mesh == NULL) {
                psys_disable_all(ob);
 
-               dm = mesh_get_derived_final(depsgraph, scene, ob, 0);
+               /* TODO(Sybren): port to Mesh when we have decided how to handle derivedFinal and derivedDeform */
+               DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, 0);
                if (dm == NULL)
                        dm = mesh_get_derived_deform(depsgraph, scene, ob, 0);
 
@@ -3392,10 +3394,13 @@ static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, De
 
                if (dm == NULL)
                        return 0;
+
+               mesh = BKE_id_new_nomain(ID_ME, NULL);
+               DM_to_mesh(dm, mesh, ob, CD_MASK_EVERYTHING, false);
        }
 
        /* BMESH_ONLY, deform dm may not have tessface */
-       DM_ensure_tessface(dm);
+       BKE_mesh_tessface_ensure(mesh);
        
 
        if (pa_minmax==0) {
@@ -3408,9 +3413,9 @@ static int particle_intersect_dm(const bContext *C, Scene *scene, Object *ob, De
                copy_v3_v3(p_max, pa_minmax+3);
        }
 
-       totface=dm->getNumTessFaces(dm);
-       mface=dm->getTessFaceDataArray(dm, CD_MFACE);
-       mvert=dm->getVertDataArray(dm, CD_MVERT);
+       totface = mesh->totface;
+       mface = mesh->mface;
+       mvert = mesh->mvert;
 
        /* lets intersect the faces */
        for (i=0; i<totface; i++, mface++) {
@@ -3504,7 +3509,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
        Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene= data->scene;
        Object *ob= data->ob;
-       DerivedMesh *dm;
+       Mesh *mesh;
        PTCacheEdit *edit = data->edit;
        ParticleSystem *psys= edit->psys;
        ParticleData *add_pars;
@@ -3537,13 +3542,13 @@ static int brush_add(const bContext *C, PEData *data, short number)
 
        timestep= psys_get_timestep(&sim);
 
-       if (psys->part->use_modifier_stack || psmd->dm_final->deformedOnly) {
-               dm = psmd->dm_final;
+       if (psys->part->use_modifier_stack || psmd->mesh_final->runtime.deformed_only) {
+               mesh = psmd->mesh_final;
        }
        else {
-               dm = psmd->dm_deformed;
+               mesh = psmd->mesh_deformed;
        }
-       BLI_assert(dm);
+       BLI_assert(mesh);
 
        for (i=0; i<number; i++) {
                if (number>1) {
@@ -3570,16 +3575,16 @@ static int brush_add(const bContext *C, PEData *data, short number)
                min_d=2.0;
                
                /* warning, returns the derived mesh face */
-               if (particle_intersect_dm(C, scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) {
-                       if (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly) {
+               if (particle_intersect_mesh(C, scene, ob, mesh, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) {
+                       if (psys->part->use_modifier_stack && !psmd->mesh_final->runtime.deformed_only) {
                                add_pars[n].num = add_pars[n].num_dmcache;
                                add_pars[n].num_dmcache = DMCACHE_ISCHILD;
                        }
-                       else if (dm == psmd->dm_deformed) {
+                       else if (mesh == psmd->mesh_deformed) {
                                /* Final DM is not same topology as orig mesh, we have to map num_dmcache to real final dm. */
                                add_pars[n].num = add_pars[n].num_dmcache;
                                add_pars[n].num_dmcache = psys_particle_dm_face_lookup(
-                                                             psmd->dm_final, psmd->dm_deformed,
+                                                             psmd->mesh_final, psmd->mesh_deformed,
                                                              add_pars[n].num, add_pars[n].fuv, NULL);
                        }
                        else {
@@ -3621,7 +3626,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
                        tree=BLI_kdtree_new(psys->totpart);
                        
                        for (i=0, pa=psys->particles; i<totpart; i++, pa++) {
-                               psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0);
+                               psys_particle_on_dm(psmd->mesh_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0);
                                BLI_kdtree_insert(tree, i, cur_co);
                        }
 
@@ -3665,7 +3670,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
                                int w, maxw;
                                float maxd, totw=0.0, weight[3];
 
-                               psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0);
+                               psys_particle_on_dm(psmd->mesh_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0);
                                maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3);
 
                                maxd= ptn[maxw-1].dist;
@@ -3730,7 +3735,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
                                }
                        }
                        for (k=0, hkey=pa->hair; k<pset->totaddkey; k++, hkey++) {
-                               psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat);
+                               psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat);
                                invert_m4_m4(imat, hairmat);
                                mul_m4_v3(imat, hkey->co);
                        }
@@ -3922,7 +3927,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
                                case PE_BRUSH_PUFF:
                                {
                                        if (edit->psys) {
-                                               data.dm= psmd->dm_final;
+                                               data.mesh = psmd->mesh_final;
                                                data.mval= mval;
                                                data.rad= pe_brush_size_get(scene, brush);
                                                data.select= selected;
@@ -3978,7 +3983,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
                                case PE_BRUSH_WEIGHT:
                                {
                                        if (edit->psys) {
-                                               data.dm= psmd->dm_final;
+                                               data.mesh = psmd->mesh_final;
                                                data.mval= mval;
                                                data.rad= pe_brush_size_get(scene, brush);
 
@@ -4325,7 +4330,7 @@ int PE_minmax(Scene *scene, ViewLayer *view_layer, float min[3], float max[3])
 
        LOOP_VISIBLE_POINTS {
                if (psys)
-                       psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat);
+                       psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat);
 
                LOOP_SELECTED_KEYS {
                        copy_v3_v3(co, key->co);
@@ -4363,7 +4368,7 @@ void PE_create_particle_edit(
        }
 
        /* no psmd->dm happens in case particle system modifier is not enabled */
-       if (!(psys && psmd_eval && psmd_eval->dm_final) && !cache)
+       if (!(psys && psmd_eval && psmd_eval->mesh_final) && !cache)
                return;
 
        if (cache && cache->flag & PTCACHE_DISK_CACHE)
index 79d52ab..cb7c90a 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_scene_types.h"
@@ -48,6 +49,7 @@
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
+#include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
 #include "BKE_particle.h"
@@ -574,7 +576,7 @@ static void disconnect_hair(
                        point++;
                }
 
-               psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat);
+               psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat);
 
                for (k=0, key=pa->hair; k<pa->totkey; k++, key++) {
                        mul_m4_v3(hairmat, key->co);
@@ -653,13 +655,13 @@ static bool remap_hair_emitter(
        MFace *mface = NULL, *mf;
        MEdge *medge = NULL, *me;
        MVert *mvert;
-       DerivedMesh *dm, *target_dm;
+       Mesh *mesh, *target_mesh;
        int numverts;
        int i, k;
        float from_ob_imat[4][4], to_ob_imat[4][4];
        float from_imat[4][4], to_imat[4][4];
 
-       if (!target_psmd->dm_final)
+       if (!target_psmd->mesh_final)
                return false;
        if (!psys->part || psys->part->type != PART_HAIR)
                return false;
@@ -673,40 +675,46 @@ static bool remap_hair_emitter(
        invert_m4_m4(from_imat, from_mat);
        invert_m4_m4(to_imat, to_mat);
        
-       if (target_psmd->dm_final->deformedOnly) {
+       if (target_psmd->mesh_final->runtime.deformed_only) {
                /* we don't want to mess up target_psmd->dm when converting to global coordinates below */
-               dm = target_psmd->dm_final;
+               mesh = target_psmd->mesh_final;
        }
        else {
-               dm = target_psmd->dm_deformed;
+               mesh = target_psmd->mesh_deformed;
        }
-       target_dm = target_psmd->dm_final;
-       if (dm == NULL) {
+       target_mesh = target_psmd->mesh_final;
+       if (mesh == NULL) {
                return false;
        }
        /* don't modify the original vertices */
-       dm = CDDM_copy(dm);
+       BKE_id_copy_ex(
+                   NULL, &mesh->id, (ID **)&mesh,
+                   LIB_ID_CREATE_NO_MAIN |
+                   LIB_ID_CREATE_NO_USER_REFCOUNT |
+                   LIB_ID_CREATE_NO_DEG_TAG |
+                   LIB_ID_COPY_NO_PREVIEW,
+                   false);
 
        /* BMESH_ONLY, deform dm may not have tessface */
-       DM_ensure_tessface(dm);
+       BKE_mesh_tessface_ensure(mesh);
 
-       numverts = dm->getNumVerts(dm);
-       mvert = dm->getVertArray(dm);
+       numverts = mesh->totvert;
+       mvert = mesh->mvert;
 
        /* convert to global coordinates */
        for (i=0; i<numverts; i++)
                mul_m4_v3(to_mat, mvert[i].co);
 
-       if (dm->getNumTessFaces(dm) != 0) {
-               mface = dm->getTessFaceArray(dm);
-               bvhtree_from_mesh_get(&bvhtree, dm, BVHTREE_FROM_FACES, 2);
+       if (mesh->totface != 0) {
+               mface = mesh->mface;
+               BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_FACES, 2);
        }
-       else if (dm->getNumEdges(dm) != 0) {
-               medge = dm->getEdgeArray(dm);
-               bvhtree_from_mesh_get(&bvhtree, dm, BVHTREE_FROM_EDGES, 2);
+       else if (mesh->totedge != 0) {
+               medge = mesh->medge;
+               BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_EDGES, 2);
        }
        else {
-               dm->release(dm);
+               BKE_id_free(NULL, mesh);
                return false;
        }
 
@@ -751,7 +759,7 @@ static bool remap_hair_emitter(
                        tpa->foffset = 0.0f;
 
                        tpa->num = nearest.index;
-                       tpa->num_dmcache = psys_particle_dm_face_lookup(target_dm, dm, tpa->num, tpa->fuv, NULL);
+                       tpa->num_dmcache = psys_particle_dm_face_lookup(target_mesh, mesh, tpa->num, tpa->fuv, NULL);
                }
                else {
                        me = &medge[nearest.index];
@@ -777,7 +785,7 @@ static bool remap_hair_emitter(
                                copy_m4_m4(imat, target_ob->obmat);
                        else {
                                /* note: using target_dm here, which is in target_ob object space and has full modifiers */
-                               psys_mat_hair_to_object(target_ob, target_dm, target_psys->part->from, tpa, hairmat);
+                               psys_mat_hair_to_object(target_ob, target_mesh, target_psys->part->from, tpa, hairmat);
                                invert_m4_m4(imat, hairmat);
                        }
                        mul_m4_m4m4(imat, imat, to_imat);
@@ -823,7 +831,7 @@ static bool remap_hair_emitter(
        }
 
        free_bvhtree_from_mesh(&bvhtree);
-       dm->release(dm);
+       BKE_id_free(NULL, mesh);
 
        psys_free_path_cache(target_psys, target_edit);
 
@@ -994,7 +1002,7 @@ static bool copy_particle_systems_to_object(const bContext *C,
        ModifierData *md;
        ParticleSystem *psys_start = NULL, *psys, *psys_from;
        ParticleSystem **tmp_psys;
-       DerivedMesh *final_dm;
+       Mesh *final_mesh;
        CustomDataMask cdmask;
        int i, totpsys;
 
@@ -1036,8 +1044,11 @@ static bool copy_particle_systems_to_object(const bContext *C,
        psys_start = totpsys > 0 ? tmp_psys[0] : NULL;
        
        /* get the DM (psys and their modifiers have not been appended yet) */
-       final_dm = mesh_get_derived_final(depsgraph, scene, ob_to, cdmask);
-       
+       /* TODO(Sybren): use mesh_evaluated instead */
+       DerivedMesh *final_dm = mesh_get_derived_final(depsgraph, scene, ob_to, cdmask);
+       final_mesh = BKE_id_new_nomain(ID_ME, NULL);
+       DM_to_mesh(final_dm, final_mesh, ob_to, CD_MASK_EVERYTHING, false);
+
        /* now append psys to the object and make modifiers */
        for (i = 0, psys_from = PSYS_FROM_FIRST;
             i < totpsys;
@@ -1060,10 +1071,17 @@ static bool copy_particle_systems_to_object(const bContext *C,
                modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd);
                
                psmd->psys = psys;
-               psmd->dm_final = CDDM_copy(final_dm);
-               CDDM_calc_normals(psmd->dm_final);
-               DM_ensure_tessface(psmd->dm_final);
-               
+               BKE_id_copy_ex(
+                           NULL, &final_mesh->id, (ID **)&psmd->mesh_final,
+                           LIB_ID_CREATE_NO_MAIN |
+                           LIB_ID_CREATE_NO_USER_REFCOUNT |
+                           LIB_ID_CREATE_NO_DEG_TAG |
+                           LIB_ID_COPY_NO_PREVIEW,
+                           false);
+
+               BKE_mesh_calc_normals(psmd->mesh_final);
+               BKE_mesh_tessface_ensure(psmd->mesh_final);
+
                if (psys_from->edit) {
                        copy_particle_edit(depsgraph, scene, ob_to, psys, psys_from);
                }
index 3c026f7..12229b8 100644 (file)
@@ -2027,7 +2027,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
                        if (!(point->flag & PEP_TRANSFORM)) continue;
 
                        if (psys && !(psys->flag & PSYS_GLOBAL_HAIR))
-                               psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
+                               psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles + i, mat);
 
                        for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
                                if (key->flag & PEK_USE_WCO) {
@@ -2105,7 +2105,7 @@ void flushTransParticles(TransInfo *t)
                        if (!(point->flag & PEP_TRANSFORM)) continue;
 
                        if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
-                               psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
+                               psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles + i, mat);
                                invert_m4_m4(imat, mat);
 
                                for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
index 31900b9..bd33744 100644 (file)
@@ -738,8 +738,8 @@ typedef struct ParticleSystemModifierData {
        ModifierData modifier;
 
        struct ParticleSystem *psys;
-       struct DerivedMesh *dm_final;  /* Final DM - its topology may differ from orig mesh. */
-       struct DerivedMesh *dm_deformed;  /* Deformed-onle DM - its topology is same as orig mesh one. */
+       struct Mesh *mesh_final;  /* Final Mesh - its topology may differ from orig mesh. */
+       struct Mesh *mesh_deformed;  /* Deformed-only Mesh - its topology is same as orig mesh one. */
        int totdmvert, totdmedge, totdmface;
        short flag, pad;
 } ParticleSystemModifierData;
index 3e1e301..70afef9 100644 (file)
@@ -284,7 +284,7 @@ typedef struct ParticleSystem {
        ListBase pathcachebufs, childcachebufs; /* buffers for the above */
 
        struct ClothModifierData *clmd;                                 /* cloth simulation for hair */
-       struct DerivedMesh *hair_in_dm, *hair_out_dm;   /* input/output for cloth simulation */
+       struct Mesh *hair_in_mesh, *hair_out_mesh;      /* input/output for cloth simulation */
 
        struct Object *target_ob;
 
index f0d5a7e..2991d7a 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"
@@ -179,7 +182,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
@@ -206,15 +209,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);
                }
@@ -234,17 +237,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);
@@ -259,15 +262,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);
                }
@@ -286,14 +289,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 */
@@ -303,8 +306,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;
@@ -423,9 +426,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) {
@@ -455,7 +458,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;
 
@@ -497,7 +500,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;
 
@@ -521,7 +524,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;
@@ -538,8 +541,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);
                }
@@ -550,7 +553,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;
@@ -567,8 +570,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);
index aab6c62..6688236 100644 (file)
@@ -1009,7 +1009,7 @@ static DerivedMesh *applyModifier(
 
                if (psys == NULL || psys->totpart == 0) return derivedData;
                if (psys->part == NULL || psys->particles == NULL) return derivedData;
-               if (psmd->dm_final == NULL) return derivedData;
+               if (psmd->mesh_final == NULL) return derivedData;
 
                DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
 
index 3a781a5..c6eb2f7 100644 (file)
@@ -405,7 +405,7 @@ static DerivedMesh *applyModifier(
                                                ChildParticle *cpa = psys->child + (p - psys->totpart);
                                                pa = psys->particles + (between? cpa->pa[0]: cpa->parent);
                                        }
-                                       psys_mat_hair_to_global(sim.ob, sim.psmd->dm_final, sim.psys->part->from, pa, hairmat);
+                                       psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat);
                                        copy_m3_m4(mat, hairmat);
                                        /* to quaternion */
                                        mat3_to_quat(frame, mat);
index ad24ce9..c2493e6 100644 (file)
@@ -42,6 +42,8 @@
 
 
 #include "BKE_cdderivedmesh.h"
+#include "BKE_mesh.h"
+#include "BKE_library.h"
 #include "BKE_modifier.h"
 #include "BKE_particle.h"
 
@@ -52,22 +54,20 @@ static void initData(ModifierData *md)
 {
        ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
        psmd->psys = NULL;
-       psmd->dm_final = NULL;
-       psmd->dm_deformed = NULL;
+       psmd->mesh_final = NULL;
+       psmd->mesh_deformed = NULL;
        psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
 }
 static void freeData(ModifierData *md)
 {
        ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
 
-       if (psmd->dm_final) {
-               psmd->dm_final->needsFree = true;
-               psmd->dm_final->release(psmd->dm_final);
-               psmd->dm_final = NULL;
-               if (psmd->dm_deformed) {
-                       psmd->dm_deformed->needsFree = true;
-                       psmd->dm_deformed->release(psmd->dm_deformed);
-                       psmd->dm_deformed = NULL;
+       if (psmd->mesh_final) {
+               BKE_id_free(NULL, psmd->mesh_final);
+               psmd->mesh_final = NULL;
+               if (psmd->mesh_deformed) {
+                       BKE_id_free(NULL, psmd->mesh_deformed);
+                       psmd->mesh_deformed = NULL;
                }
        }
        psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
@@ -87,8 +87,8 @@ static void copyData(const ModifierData *md, ModifierData *target)
 
        modifier_copyData_generic(md, target);
 
-       tpsmd->dm_final = NULL;
-       tpsmd->dm_deformed = NULL;
+       tpsmd->mesh_final = NULL;
+       tpsmd->mesh_deformed = NULL;
        tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
 }
 
@@ -101,14 +101,13 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
 /* saves the current emitter state for a particle system and calculates particles */
 static void deformVerts(
         ModifierData *md, const ModifierEvalContext *ctx,
-        DerivedMesh *derivedData,
+        Mesh *mesh,
         float (*vertexCos)[3],
         int UNUSED(numVerts))
 {
-       DerivedMesh *dm = derivedData;
+       Mesh *mesh_src = mesh;
        ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
        ParticleSystem *psys = NULL;
-       bool needsFree = false;
        /* float cfra = BKE_scene_frame_get(md->scene); */  /* UNUSED */
 
        if (ctx->object->particlesystem.first)
@@ -119,27 +118,24 @@ static void deformVerts(
        if (!psys_check_enabled(ctx->object, psys, (ctx->flag & MOD_APPLY_RENDER) != 0))
                return;
 
-       if (dm == NULL) {
-               dm = get_dm(ctx->object, NULL, NULL, vertexCos, false, true);
-
-               if (!dm)
+       if (mesh_src == NULL) {
+               mesh_src = get_mesh(ctx->object, NULL, NULL, vertexCos, false, true);
+               if (mesh_src == NULL) {
                        return;
-
-               needsFree = true;
+               }
        }
 
        /* clear old dm */
-       if (psmd->dm_final) {
-               psmd->dm_final->needsFree = true;
-               psmd->dm_final->release(psmd->dm_final);
-               if (psmd->dm_deformed) {
-                       psmd->dm_deformed->needsFree = 1;
-                       psmd->dm_deformed->release(psmd->dm_deformed);
-                       psmd->dm_deformed = NULL;
+       if (psmd->mesh_final) {
+               BKE_id_free(NULL, psmd->mesh_final);
+               psmd->mesh_final = NULL;
+               if (psmd->mesh_deformed) {
+                       BKE_id_free(NULL, psmd->mesh_deformed);
+                       psmd->mesh_deformed = NULL;
                }
        }
        else if (psmd->flag & eParticleSystemFlag_file_loaded) {
-               /* in file read dm just wasn't saved in file so no need to reset everything */
+               /* in file read mesh just wasn't saved in file so no need to reset everything */
                psmd->flag &= ~eParticleSystemFlag_file_loaded;
        }
        else {
@@ -147,43 +143,49 @@ static void deformVerts(
                psys->recalc |= PSYS_RECALC_RESET;
        }
 
-       /* make new dm */
-       psmd->dm_final = CDDM_copy(dm);
-       CDDM_apply_vert_coords(psmd->dm_final, vertexCos);
-       CDDM_calc_normals(psmd->dm_final);
+       /* make new mesh */
+       BKE_id_copy_ex(NULL, &mesh_src->id, (ID **)&psmd->mesh_final,
+                      LIB_ID_CREATE_NO_MAIN |
+                      LIB_ID_CREATE_NO_USER_REFCOUNT |
+                      LIB_ID_CREATE_NO_DEG_TAG |
+                      LIB_ID_COPY_NO_PREVIEW,
+                      false);
+       BKE_mesh_apply_vert_coords(psmd->mesh_final, vertexCos);
+       BKE_mesh_calc_normals(psmd->mesh_final);
 
-       if (needsFree) {
-               dm->needsFree = true;
-               dm->release(dm);
-       }
+       BKE_mesh_tessface_ensure(psmd->mesh_final);
 
-       /* protect dm */
-       psmd->dm_final->needsFree = false;
-
-       DM_ensure_tessface(psmd->dm_final);
-
-       if (!psmd->dm_final->deformedOnly) {
+       if (!psmd->mesh_final->runtime.deformed_only) {
                /* XXX Think we can assume here that if current DM is not only-deformed, ob->deformedOnly has been set.
                 *     This is awfully weak though. :| */
                if (ctx->object->derivedDeform) {
-                       psmd->dm_deformed = CDDM_copy(ctx->object->derivedDeform);
+                       DM_to_mesh(ctx->object->derivedDeform, psmd->mesh_deformed, ctx->object, CD_MASK_EVERYTHING, false);
                }
                else {  /* Can happen in some cases, e.g. when rendering from Edit mode... */
-                       psmd->dm_deformed = CDDM_from_mesh((Mesh *)ctx->object->data);
+                       BKE_id_copy_ex(NULL, &mesh_src->id, (ID **)&psmd->mesh_deformed,
+                                      LIB_ID_CREATE_NO_MAIN |
+                                      LIB_ID_CREATE_NO_USER_REFCOUNT |
+                                      LIB_ID_CREATE_NO_DEG_TAG |
+                                      LIB_ID_COPY_NO_PREVIEW,
+                                      false);
                }
-               DM_ensure_tessface(psmd->dm_deformed);
+               BKE_mesh_tessface_ensure(psmd->mesh_deformed);
+       }
+
+       if (mesh_src != psmd->mesh_final && mesh_src != mesh) {
+               BKE_id_free(NULL, mesh_src);
        }
 
        /* report change in mesh structure */
-       if (psmd->dm_final->getNumVerts(psmd->dm_final) != psmd->totdmvert ||
-           psmd->dm_final->getNumEdges(psmd->dm_final) != psmd->totdmedge ||
-           psmd->dm_final->getNumTessFaces(psmd->dm_final) != psmd->totdmface)
+       if (psmd->mesh_final->totvert != psmd->totdmvert ||
+           psmd->mesh_final->totedge != psmd->totdmedge ||
+           psmd->mesh_final->totface != psmd->totdmface)
        {
                psys->recalc |= PSYS_RECALC_RESET;
 
-               psmd->totdmvert = psmd->dm_final->getNumVerts(psmd->dm_final);
-               psmd->totdmedge = psmd->dm_final->getNumEdges(psmd->dm_final);
-               psmd->totdmface = psmd->dm_final->getNumTessFaces(psmd->dm_final);
+               psmd->totdmvert = psmd->mesh_final->totvert;
+               psmd->totdmedge = psmd->mesh_final->totedge;
+               psmd->totdmface = psmd->mesh_final->totface;
        }
 
        if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) {
@@ -224,14 +226,14 @@ ModifierTypeInfo modifierType_ParticleSystem = {
 
        /* copyData */          copyData,
 
-       /* deformVerts_DM */    deformVerts,
+       /* deformVerts_DM */    NULL,
        /* deformVertsEM_DM */  NULL,
        /* deformMatrices_DM */ NULL,
        /* deformMatricesEM_DM*/NULL,
        /* applyModifier_DM */  NULL,
        /* applyModifierEM_DM */NULL,
 
-       /* deformVerts */       NULL,
+       /* deformVerts */       deformVerts,
        /* deformMatrices */    NULL,
        /* deformVertsEM */     NULL,
        /* deformMatricesEM */  NULL,