diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2014-11-14 14:54:46 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2014-11-14 14:54:46 +0300 |
commit | a8c7a988263c3e45145e365e40c7773e0327dd0e (patch) | |
tree | 3dba6183a4d6dbca26ce07b32f5184f38ba62182 | |
parent | 0f91a7c528096610b1f85815d0b9445f7cd3b900 (diff) |
Add Mesh's counterpart to BM_mesh_topology_hash.
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.c | 69 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 7 |
3 files changed, 76 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index b2b9e37f500..ef540d4a636 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -282,7 +282,8 @@ void BKE_mesh_calc_relative_deform( const float (*vert_cos_org)[3], float (*vert_cos_new)[3]); - +/* Topology. */ +unsigned int BKE_mesh_topology_hash(struct Mesh *mesh); /* *** mesh_validate.c *** */ diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 4c9e44682c3..a7610af504b 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -42,6 +42,7 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_bitmap.h" +#include "BLI_hash_mm2a.h" #include "BLI_polyfill2d.h" #include "BLI_linklist.h" #include "BLI_linklist_stack.h" @@ -2253,3 +2254,71 @@ void BKE_mesh_calc_relative_deform( MEM_freeN(vert_accum); } /** \} */ + +/* -------------------------------------------------------------------- */ + +/** \name Mesh Topology Hashing + * \{ */ + +/** + * This function computes a hash of current mesh's topology. Allows to detect any topology change. + * + * Similar to `BM_mesh_topology_hash()`. + * + * \param mesh The Mesh. + * \return The hash, as an unsigned integer. + * + * \note We use vertex indices as core 'reference'. + */ +unsigned int BKE_mesh_topology_hash(Mesh *mesh) +{ + int me_idx, mp_idx; + + BLI_HashMurmur2A mm2; + + unsigned int seed = (unsigned int)mesh->totvert + (unsigned int)mesh->totedge + + (unsigned int)mesh->totloop + (unsigned int)mesh->totpoly; + + if (!seed) { + return seed; + } + + if (mesh->totedge == 0) { + /* Cloud mesh, only vertices, totvert is good enough. */ + return seed; + } + + /* Init the murmur hash. */ + BLI_hash_mm2a_init(&mm2, seed); + + /* Compute edge topology, using only vert indices. */ + for (me_idx = 0; me_idx < mesh->totedge; me_idx++) { + MEdge *me = &mesh->medge[me_idx]; + + /* Edge topology is fully defined by its two vertices. */ + BLI_hash_mm2a_add_int(&mm2, (int)me->v1); + BLI_hash_mm2a_add_int(&mm2, (int)me->v2); + } + + if (mesh->totpoly == 0) { + /* No poly (nor loop), we are done. */ + return (unsigned int)BLI_hash_mm2a_end(&mm2); + } + + /* Else, we have to check all polys too - it *is* possible to change topology + * without affecting edges nor changing numbers of verts/edges/loops/polys! */ + for (mp_idx = 0; mp_idx < mesh->totpoly; mp_idx++) { + MPoly *mp = &mesh->mpoly[mp_idx]; + int ml_idx = mp->loopstart; + const int ml_idx_end = mp->loopstart + mp->totloop; + + /* Poly topology is fully defined by its vertices and their order in it. */ + for (; ml_idx < ml_idx_end; ml_idx++) { + MLoop *ml = &mesh->mloop[ml_idx]; + + BLI_hash_mm2a_add_int(&mm2, (int)ml->v); + } + } + + return (unsigned int)BLI_hash_mm2a_end(&mm2); +} diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 64df3af8643..09e4ffc87cb 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -2354,6 +2354,8 @@ int BM_mesh_calc_edge_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde /** * Calculate a hash of current topology. * + * Similar to `BKE_mesh_topology_hash()`. + * * \param bm The BMesh. * \return The hash, as an unsigned integer. * @@ -2368,7 +2370,8 @@ unsigned int BM_mesh_topology_hash(BMesh *bm) BLI_HashMurmur2A mm2; - unsigned int seed = (unsigned int)(bm->totvert + bm->totedge + bm->totloop + bm->totface); + unsigned int seed = (unsigned int)bm->totvert + (unsigned int)bm->totedge + + (unsigned int)bm->totloop + (unsigned int)bm->totface; if (!seed) { return seed; @@ -2398,7 +2401,7 @@ unsigned int BM_mesh_topology_hash(BMesh *bm) } /* Else, we have to check all faces too - it *is* possible to change topology - * without affecting edges nor changing numbers of verts/edges/faces/loops! */ + * without affecting edges nor changing numbers of verts/edges/loops/faces! */ BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) { /* Face topology is fully defined by its vertices and their order in it. */ BM_ITER_ELEM(l, &iter, f, BM_LOOPS_OF_FACE) { |