diff options
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 25 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_edgehash.h | 26 | ||||
-rw-r--r-- | source/blender/blenlib/intern/edgehash.c | 51 |
3 files changed, 102 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 97068cc5afb..b937c4fb71d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5,6 +5,7 @@ #include "BLI_blenlib.h" #include "BLI_rand.h" #include "BLI_arithb.h" +#include "BLI_edgehash.h" #include "MEM_guardedalloc.h" @@ -803,6 +804,8 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void * dmd->faceCount = 0; if(LOD_LoadMesh(&lod) ) { if( LOD_PreprocessMesh(&lod) ) { + EdgeHash *eh; + EdgeHashIterator *ehi; /* we assume the decim_faces tells how much to reduce */ @@ -823,6 +826,7 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void * VECCOPY(mv->co, vbCo); } + eh = BLI_edgehash_new(); for(a=0; a<lod.face_num; a++) { MFace *mf = &ndlm->mface[a]; int *tri = &lod.triangle_index_buffer[a*3]; @@ -830,7 +834,28 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void * mf->v2 = tri[1]; mf->v3 = tri[2]; test_index_face(mface, NULL, NULL, 3); + + if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2)) + BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL); + if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3)) + BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL); + if (!BLI_edgehash_haskey(eh, mf->v1, mf->v3)) + BLI_edgehash_insert(eh, mf->v1, mf->v3, NULL); + } + + ndlm->totedge = BLI_edgehash_size(eh); + ndlm->medge = MEM_callocN(ndlm->totedge*sizeof(MEdge), "mdge"); + ehi = BLI_edgehashIterator_new(eh); + for (a=0; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { + MEdge *med = &ndlm->medge[a++]; + + BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2); + + med->flag = ME_EDGEDRAW|ME_EDGERENDER; } + BLI_edgehashIterator_free(ehi); + + BLI_edgehash_free(eh, NULL); } else { modifier_setError(md, "Out of memory."); diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h index 4f8a85b2eea..6b7eaedea2f 100644 --- a/source/blender/blenlib/BLI_edgehash.h +++ b/source/blender/blenlib/BLI_edgehash.h @@ -36,7 +36,9 @@ #define BLI_EDGEHASH_H struct EdgeHash; +struct EdgeHashIterator; typedef struct EdgeHash EdgeHash; +typedef struct EdgeHashIterator EdgeHashIterator; typedef void (*EdgeHashFreeFP)(void *key); @@ -69,5 +71,29 @@ int BLI_edgehash_size (EdgeHash *eh); /* Remove all edges from hash. */ void BLI_edgehash_clear (EdgeHash *eh, EdgeHashFreeFP valfreefp); +/***/ + + /** + * Create a new EdgeHashIterator. The hash table must not be mutated + * while the iterator is in use, and the iterator will step exactly + * BLI_edgehash_size(gh) times before becoming done. + */ +EdgeHashIterator* BLI_edgehashIterator_new (EdgeHash *eh); + + /* Free an EdgeHashIterator. */ +void BLI_edgehashIterator_free (EdgeHashIterator *ehi); + + /* Retrieve the key from an iterator. */ +void BLI_edgehashIterator_getKey (EdgeHashIterator *ehi, int *v0_r, int *v1_r); + + /* Retrieve the value from an iterator. */ +void* BLI_edgehashIterator_getValue (EdgeHashIterator *ehi); + + /* Steps the iterator to the next index. */ +void BLI_edgehashIterator_step (EdgeHashIterator *ehi); + + /* Determine if an iterator is done. */ +int BLI_edgehashIterator_isDone (EdgeHashIterator *ehi); + #endif diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index f67d07a0649..8fae0f63746 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -167,3 +167,54 @@ void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp) { MEM_freeN(eh); } + +/***/ + +struct EdgeHashIterator { + EdgeHash *eh; + int curBucket; + Entry *curEntry; +}; + +EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) { + EdgeHashIterator *ehi= malloc(sizeof(*ehi)); + ehi->eh= eh; + ehi->curEntry= NULL; + ehi->curBucket= -1; + while (!ehi->curEntry) { + ehi->curBucket++; + if (ehi->curBucket==ehi->eh->nbuckets) + break; + ehi->curEntry= ehi->eh->buckets[ehi->curBucket]; + } + return ehi; +} +void BLI_edgehashIterator_free(EdgeHashIterator *ehi) { + free(ehi); +} + +void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, int *v0_r, int *v1_r) { + if (ehi->curEntry) { + *v0_r = ehi->curEntry->v0; + *v1_r = ehi->curEntry->v1; + } +} +void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi) { + return ehi->curEntry?ehi->curEntry->val:NULL; +} + +void BLI_edgehashIterator_step(EdgeHashIterator *ehi) { + if (ehi->curEntry) { + ehi->curEntry= ehi->curEntry->next; + while (!ehi->curEntry) { + ehi->curBucket++; + if (ehi->curBucket==ehi->eh->nbuckets) + break; + ehi->curEntry= ehi->eh->buckets[ehi->curBucket]; + } + } +} +int BLI_edgehashIterator_isDone(EdgeHashIterator *ehi) { + return !ehi->curEntry; +} + |