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 b31a185e39b6b940acf1359ae372667bc040504d..e7cc474e2e8d2d62f3187ee828ab9e9dfd5a1f50 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 7525b4968158d3388c92fb01669e0a677ddbebc9..25b91be3791550e9aa41a21f24c8c2d79ab07839 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 097532ff2c382ef87ad1c9314c032412ccf9e420..b6a87ae333e592f9d51dc3998d94f143fd067e1f 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 fc6a42e5cf8686057071b99a1a46489adc8420b3..bced9a1e019202dad67f72fdb0db09c3450ee41b 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 ed09e89a770c1340f758103faccf0351003a6a48..2e07616d6a88ed9d21b902fba972f7543d1306e2 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 bf21e18f4b94bff433a88c1d530c1b4b6c624ab4..e85a3f15022b8c2c5cd425acf6783e977d07d029 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 6a9191b7948a95a6f6b3d0f0ab3b4cf7c82d8fab..ff61faf9cd26992c254e497c43c64333fe64d4a9 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 6c617b52734bc0c323e4676fd4950a075a062256..9c020a84536ea25bebd598fd024dd0a3a9c646b5 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 b8b24ac8afcf0261ad9abdee575234ace6c77b03..c6cc243638b007c5dab05f22963a349b97e3ee81 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 787cf7f0524e8fe125e2761f13c477de6cb2ccf8..dfa5a51a775932dad7de717c880e889d6e09e3d1 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 e8f3e5927150486ac2da5794b97256f1a3634b87..ab44e017fc68e85b1e18110728ca32ffe9ad9e94 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 22bfd8eedeaafc29c976958c6b2d5b1bde2f22bf..4c078d2ac8b1bd01e197cdabd778e3736f0f1ff7 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 83458127820a8b21112dd4d4571fd9dc52671028..9b86f904161ece873008d285abbec9fecb7c2415 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 3df934a8dca2a5d849db0e163944991f164457fe..164001b61507cee22b2a7e90c4c3ed45ee6b324b 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 79d52abb32d18a75a59697dc81c67b6dd48e3773..cb7c90a6c3d78fe4c6b4f44534329173c3ff4568 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 3c026f7176996b51aad5475cdbea3d0579242aa0..12229b8c940176d03303ba0450565993d869f5b1 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 31900b985640871e7d40e2d84ca1795531acc613..bd337443edcfe04445ff10f12fdc22f21d426dea 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 3e1e301acccb435fe8e4850d4fcf5cb7074e5cee..70afef9b874288ea639fde5f1145cf7c8f6ae26b 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 f0d5a7e7c2e79515d98313e4039f7c9a98c60a52..2991d7a48603a4679ac8ac512057787c5654c029 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 aab6c62ee7eef07eafee98e02e802567850fa93a..6688236a558f42aada8814626ca26b61d17417e3 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 3a781a586342c358051ffa5a09a7420889f4bf04..c6eb2f7302778bbe9114df6869591656233acce1 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 ad24ce9262647eed7b3403dfbdb1ca99c8f34a13..c2493e6d8f39ac74cff484eb16d6e7b5543fafb7 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,