diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_mesh.h | 10 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_utils.c | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_mirror.c | 127 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 118 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_edit.c | 133 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_object.c | 76 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 4 |
7 files changed, 369 insertions, 101 deletions
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++) { |