diff options
22 files changed, 771 insertions, 461 deletions
diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc index b31a185e39b..e7cc474e2e8 100644 --- a/source/blender/alembic/intern/abc_hair.cc +++ b/source/blender/alembic/intern/abc_hair.cc @@ -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; } diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 7525b496815..25b91be3791 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -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 diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 097532ff2c3..b6a87ae333e 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -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); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index fc6a42e5cf8..bced9a1e019 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -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); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index ed09e89a770..2e07616d6a8 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -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; diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index bf21e18f4b9..e85a3f15022 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -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; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 6a9191b7948..ff61faf9cd2 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -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 */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6c617b52734..9c020a84536 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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; diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index b8b24ac8afc..c6cc243638b 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -38,10 +38,12 @@ #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); } } diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 787cf7f0524..dfa5a51a775 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -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); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index e8f3e592715..ab44e017fc6 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -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); diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c index 22bfd8eedea..4c078d2ac8b 100644 --- a/source/blender/editors/mesh/mesh_mirror.c +++ b/source/blender/editors/mesh/mesh_mirror.c @@ -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,11 +240,62 @@ 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; BMEditMesh *em = dm ? NULL : me->edit_btmesh; @@ -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; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 83458127820..9b86f904161 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -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; } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 3df934a8dca..164001b6150 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -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) diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 79d52abb32d..cb7c90a6c3d 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -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); } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 3c026f71769..12229b8c940 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -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++) { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 31900b98564..bd337443edc 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -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; diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 3e1e301accc..70afef9b874 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -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; diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index f0d5a7e7c2e..2991d7a4860 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -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); diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index aab6c62ee7e..6688236a558 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -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 */ diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 3a781a58634..c6eb2f73027 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -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); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index ad24ce92626..c2493e6d8f3 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -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, |