From ccc3c2dbda36f00e74064e993d7e98bf8ab32a58 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 20 Jul 2015 15:05:16 +0200 Subject: CCGSubSurf: Split file into several smaller ones This is a preparation commit for having OpenSubdiv integrated into Blender and new layout is the following: - CCGSubSurf.c contains implementation of common functions used by both legacy subdivisions code and by the new code in the future. - CCGSubSurf_inline.h contains internal functions which are to be inlined due to the performance reasons. Those functions are only ment to be used bu CCGSubSurf* files. - CCGSubSurf_intern.h contains declarations of private functions and data structures used by CCGSubSurf module. - CCGSubSurf_legacy.c contains legacy implementation of subdivision algorithm. - CCHSubSurf_util.c contains utility functions which are not directly related on the subdivision code (i.e. debug functions, hash implementation etc). There should be no functional changes so far. --- source/blender/blenkernel/intern/CCGSubSurf.c | 1843 ++----------------------- 1 file changed, 91 insertions(+), 1752 deletions(-) (limited to 'source/blender/blenkernel/intern/CCGSubSurf.c') diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index cadca6b2623..a60e1fa3076 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -30,222 +30,17 @@ #include "BLI_sys_types.h" // for intptr_t support #include "BLI_utildefines.h" /* for BLI_assert */ +#include "BLI_math.h" #include "BKE_ccg.h" #include "CCGSubSurf.h" +#include "CCGSubSurf_intern.h" #include "BKE_subsurf.h" -/* used for normalize_v3 in BLI_math_vector - * float.h's FLT_EPSILON causes trouble with subsurf normals - campbell */ -#define EPSILON (1.0e-35f) - -/* With this limit a single triangle becomes over 3 million faces */ -#define CCGSUBSURF_LEVEL_MAX 11 - -/***/ - -typedef unsigned char byte; - -/***/ - -static int kHashSizes[] = { - 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, - 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, - 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459 -}; - -typedef struct _EHEntry EHEntry; -struct _EHEntry { - EHEntry *next; - void *key; -}; -typedef struct _EHash { - EHEntry **buckets; - int numEntries, curSize, curSizeIdx; - - CCGAllocatorIFC allocatorIFC; - CCGAllocatorHDL allocator; -} EHash; - -#define EHASH_alloc(eh, nb) ((eh)->allocatorIFC.alloc((eh)->allocator, nb)) -#define EHASH_free(eh, ptr) ((eh)->allocatorIFC.free((eh)->allocator, ptr)) - -#define EHASH_hash(eh, item) (((uintptr_t) (item)) % ((unsigned int) (eh)->curSize)) - -static void ccgSubSurf__sync(CCGSubSurf *ss); -static int _edge_isBoundary(const CCGEdge *e); - -static EHash *_ehash_new(int estimatedNumEntries, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) -{ - EHash *eh = allocatorIFC->alloc(allocator, sizeof(*eh)); - eh->allocatorIFC = *allocatorIFC; - eh->allocator = allocator; - eh->numEntries = 0; - eh->curSizeIdx = 0; - while (kHashSizes[eh->curSizeIdx] < estimatedNumEntries) - eh->curSizeIdx++; - eh->curSize = kHashSizes[eh->curSizeIdx]; - eh->buckets = EHASH_alloc(eh, eh->curSize * sizeof(*eh->buckets)); - memset(eh->buckets, 0, eh->curSize * sizeof(*eh->buckets)); - - return eh; -} -typedef void (*EHEntryFreeFP)(EHEntry *, void *); -static void _ehash_free(EHash *eh, EHEntryFreeFP freeEntry, void *userData) -{ - int numBuckets = eh->curSize; - - while (numBuckets--) { - EHEntry *entry = eh->buckets[numBuckets]; - - while (entry) { - EHEntry *next = entry->next; - - freeEntry(entry, userData); - - entry = next; - } - } - - EHASH_free(eh, eh->buckets); - EHASH_free(eh, eh); -} - -static void _ehash_insert(EHash *eh, EHEntry *entry) -{ - int numBuckets = eh->curSize; - int hash = EHASH_hash(eh, entry->key); - entry->next = eh->buckets[hash]; - eh->buckets[hash] = entry; - eh->numEntries++; - - if (UNLIKELY(eh->numEntries > (numBuckets * 3))) { - EHEntry **oldBuckets = eh->buckets; - eh->curSize = kHashSizes[++eh->curSizeIdx]; - - eh->buckets = EHASH_alloc(eh, eh->curSize * sizeof(*eh->buckets)); - memset(eh->buckets, 0, eh->curSize * sizeof(*eh->buckets)); - - while (numBuckets--) { - for (entry = oldBuckets[numBuckets]; entry; ) { - EHEntry *next = entry->next; - - hash = EHASH_hash(eh, entry->key); - entry->next = eh->buckets[hash]; - eh->buckets[hash] = entry; - - entry = next; - } - } - - EHASH_free(eh, oldBuckets); - } -} - -static void *_ehash_lookupWithPrev(EHash *eh, void *key, void ***prevp_r) -{ - int hash = EHASH_hash(eh, key); - void **prevp = (void **) &eh->buckets[hash]; - EHEntry *entry; - - for (; (entry = *prevp); prevp = (void **) &entry->next) { - if (entry->key == key) { - *prevp_r = (void **) prevp; - return entry; - } - } - - return NULL; -} - -static void *_ehash_lookup(EHash *eh, void *key) -{ - int hash = EHASH_hash(eh, key); - EHEntry *entry; - - for (entry = eh->buckets[hash]; entry; entry = entry->next) - if (entry->key == key) - break; - - return entry; -} - -/**/ - -static void _ehashIterator_init(EHash *eh, EHashIterator *ehi) -{ - /* fill all members */ - ehi->eh = eh; - ehi->curBucket = -1; - ehi->curEntry = NULL; - - while (!ehi->curEntry) { - ehi->curBucket++; - if (ehi->curBucket == ehi->eh->curSize) - break; - ehi->curEntry = ehi->eh->buckets[ehi->curBucket]; - } -} - -static void *_ehashIterator_getCurrent(EHashIterator *ehi) -{ - return ehi->curEntry; -} - -static void _ehashIterator_next(EHashIterator *ehi) -{ - if (ehi->curEntry) { - ehi->curEntry = ehi->curEntry->next; - while (!ehi->curEntry) { - ehi->curBucket++; - if (ehi->curBucket == ehi->eh->curSize) - break; - ehi->curEntry = ehi->eh->buckets[ehi->curBucket]; - } - } -} -static int _ehashIterator_isStopped(EHashIterator *ehi) -{ - return !ehi->curEntry; -} - -/***/ - -static void *_stdAllocator_alloc(CCGAllocatorHDL UNUSED(a), int numBytes) -{ - return MEM_mallocN(numBytes, "CCG standard alloc"); -} -static void *_stdAllocator_realloc(CCGAllocatorHDL UNUSED(a), void *ptr, int newSize, int UNUSED(oldSize)) -{ - return MEM_reallocN(ptr, newSize); -} -static void _stdAllocator_free(CCGAllocatorHDL UNUSED(a), void *ptr) -{ - MEM_freeN(ptr); -} - -static CCGAllocatorIFC *_getStandardAllocatorIFC(void) -{ - static CCGAllocatorIFC ifc; - - ifc.alloc = _stdAllocator_alloc; - ifc.realloc = _stdAllocator_realloc; - ifc.free = _stdAllocator_free; - ifc.release = NULL; - - return &ifc; -} +#include "GL/glew.h" /***/ -BLI_INLINE int ccg_gridsize(int level) -{ - BLI_assert(level > 0); - BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1); - - return (1 << (level - 1)) + 1; -} - int BKE_ccg_gridsize(int level) { return ccg_gridsize(level); @@ -259,240 +54,6 @@ int BKE_ccg_factor(int low_level, int high_level) return 1 << (high_level - low_level); } -BLI_INLINE int ccg_edgesize(int level) -{ - BLI_assert(level > 0); - BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1); - - return 1 + (1 << level); -} - -BLI_INLINE int ccg_spacing(int high_level, int low_level) -{ - BLI_assert(high_level > 0 && low_level > 0); - BLI_assert(high_level >= low_level); - BLI_assert((high_level - low_level) <= CCGSUBSURF_LEVEL_MAX); - - return 1 << (high_level - low_level); -} - -BLI_INLINE int ccg_edgebase(int level) -{ - BLI_assert(level > 0); - BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1); - - return level + (1 << level) - 1; -} - -/***/ - -#define NormZero(av) { float *_a = (float *) av; _a[0] = _a[1] = _a[2] = 0.0f; } (void)0 -#define NormCopy(av, bv) { float *_a = (float *) av, *_b = (float *) bv; _a[0] = _b[0]; _a[1] = _b[1]; _a[2] = _b[2]; } (void)0 -#define NormAdd(av, bv) { float *_a = (float *) av, *_b = (float *) bv; _a[0] += _b[0]; _a[1] += _b[1]; _a[2] += _b[2]; } (void)0 - -BLI_INLINE void Normalize(float no[3]) -{ - const float length = sqrtf(no[0] * no[0] + no[1] * no[1] + no[2] * no[2]); - - if (length > EPSILON) { - const float length_inv = 1.0f / length; - - no[0] *= length_inv; - no[1] *= length_inv; - no[2] *= length_inv; - } - else { - NormZero(no); - } -} - -/***/ - -enum { - Vert_eEffected = (1 << 0), - Vert_eChanged = (1 << 1), - Vert_eSeam = (1 << 2) -} /*VertFlags*/; -enum { - Edge_eEffected = (1 << 0) -} /*CCGEdgeFlags*/; -enum { - Face_eEffected = (1 << 0) -} /*FaceFlags*/; - -struct CCGVert { - CCGVert *next; /* EHData.next */ - CCGVertHDL vHDL; /* EHData.key */ - - short numEdges, numFaces, flags, pad; - - CCGEdge **edges; - CCGFace **faces; -// byte *levelData; -// byte *userData; -}; - -BLI_INLINE byte *VERT_getLevelData(CCGVert *v) -{ - return (byte *)(&(v)[1]); -} - -struct CCGEdge { - CCGEdge *next; /* EHData.next */ - CCGEdgeHDL eHDL; /* EHData.key */ - - short numFaces, flags; - float crease; - - CCGVert *v0, *v1; - CCGFace **faces; - -// byte *levelData; -// byte *userData; -}; - -BLI_INLINE byte *EDGE_getLevelData(CCGEdge *e) -{ - return (byte *)(&(e)[1]); -} - -struct CCGFace { - CCGFace *next; /* EHData.next */ - CCGFaceHDL fHDL; /* EHData.key */ - - short numVerts, flags, pad1, pad2; - -// CCGVert **verts; -// CCGEdge **edges; -// byte *centerData; -// byte **gridData; -// byte *userData; -}; - -BLI_INLINE CCGVert **FACE_getVerts(CCGFace *f) -{ - return (CCGVert **)(&f[1]); -} - -BLI_INLINE CCGEdge **FACE_getEdges(CCGFace *f) -{ - return (CCGEdge **)(&(FACE_getVerts(f)[f->numVerts])); -} - -BLI_INLINE byte *FACE_getCenterData(CCGFace *f) -{ - return (byte *)(&(FACE_getEdges(f)[(f)->numVerts])); -} - -typedef enum { - eSyncState_None = 0, - eSyncState_Vert, - eSyncState_Edge, - eSyncState_Face, - eSyncState_Partial -} SyncState; - -struct CCGSubSurf { - EHash *vMap; /* map of CCGVertHDL -> Vert */ - EHash *eMap; /* map of CCGEdgeHDL -> Edge */ - EHash *fMap; /* map of CCGFaceHDL -> Face */ - - CCGMeshIFC meshIFC; - - CCGAllocatorIFC allocatorIFC; - CCGAllocatorHDL allocator; - - int subdivLevels; - int numGrids; - int allowEdgeCreation; - float defaultCreaseValue; - void *defaultEdgeUserData; - - void *q, *r; - - /* data for calc vert normals */ - int calcVertNormals; - int normalDataOffset; - - /* data for paint masks */ - int allocMask; - int maskDataOffset; - - /* data for age'ing (to debug sync) */ - int currentAge; - int useAgeCounts; - int vertUserAgeOffset; - int edgeUserAgeOffset; - int faceUserAgeOffset; - - /* data used during syncing */ - SyncState syncState; - - EHash *oldVMap, *oldEMap, *oldFMap; - int lenTempArrays; - CCGVert **tempVerts; - CCGEdge **tempEdges; -}; - -#define CCGSUBSURF_alloc(ss, nb) ((ss)->allocatorIFC.alloc((ss)->allocator, nb)) -#define CCGSUBSURF_realloc(ss, ptr, nb, ob) ((ss)->allocatorIFC.realloc((ss)->allocator, ptr, nb, ob)) -#define CCGSUBSURF_free(ss, ptr) ((ss)->allocatorIFC.free((ss)->allocator, ptr)) - -/***/ - -static int VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss) -{ - int i; - for (i = 0; i < ss->meshIFC.numLayers; i++) { - if (a[i] != b[i]) - return 0; - } - return 1; -} - -static void VertDataZero(float v[], const CCGSubSurf *ss) -{ - memset(v, 0, sizeof(float) * ss->meshIFC.numLayers); -} - -static void VertDataCopy(float dst[], const float src[], const CCGSubSurf *ss) -{ - int i; - for (i = 0; i < ss->meshIFC.numLayers; i++) - dst[i] = src[i]; -} - -static void VertDataAdd(float a[], const float b[], const CCGSubSurf *ss) -{ - int i; - for (i = 0; i < ss->meshIFC.numLayers; i++) - a[i] += b[i]; -} - -static void VertDataSub(float a[], const float b[], const CCGSubSurf *ss) -{ - int i; - for (i = 0; i < ss->meshIFC.numLayers; i++) - a[i] -= b[i]; -} - -static void VertDataMulN(float v[], float f, const CCGSubSurf *ss) -{ - int i; - for (i = 0; i < ss->meshIFC.numLayers; i++) - v[i] *= f; -} - -static void VertDataAvg4(float v[], - const float a[], const float b[], - const float c[], const float d[], - const CCGSubSurf *ss) -{ - int i; - for (i = 0; i < ss->meshIFC.numLayers; i++) - v[i] = (a[i] + b[i] + c[i] + d[i]) * 0.25f; -} - /***/ static CCGVert *_vert_new(CCGVertHDL vHDL, CCGSubSurf *ss) @@ -559,24 +120,6 @@ static CCGEdge *_vert_findEdgeTo(const CCGVert *v, const CCGVert *vQ) } return NULL; } -static int _vert_isBoundary(const CCGVert *v) -{ - int i; - for (i = 0; i < v->numEdges; i++) - if (_edge_isBoundary(v->edges[i])) - return 1; - return 0; -} - -static void *_vert_getCo(CCGVert *v, int lvl, int dataSize) -{ - return &VERT_getLevelData(v)[lvl * dataSize]; -} -static float *_vert_getNo(CCGVert *v, int lvl, int dataSize, int normalDataOffset) -{ - return (float *) &VERT_getLevelData(v)[lvl * dataSize + normalDataOffset]; -} - static void _vert_free(CCGVert *v, CCGSubSurf *ss) { if (v->edges) { @@ -590,11 +133,6 @@ static void _vert_free(CCGVert *v, CCGSubSurf *ss) CCGSUBSURF_free(ss, v); } -static int VERT_seam(const CCGVert *v) -{ - return ((v->flags & Vert_eSeam) != 0); -} - /***/ static CCGEdge *_edge_new(CCGEdgeHDL eHDL, CCGVert *v0, CCGVert *v1, float crease, CCGSubSurf *ss) @@ -637,31 +175,6 @@ static void _edge_addFace(CCGEdge *e, CCGFace *f, CCGSubSurf *ss) e->faces = CCGSUBSURF_realloc(ss, e->faces, (e->numFaces + 1) * sizeof(*e->faces), e->numFaces * sizeof(*e->faces)); e->faces[e->numFaces++] = f; } -static int _edge_isBoundary(const CCGEdge *e) -{ - return e->numFaces < 2; -} - -static CCGVert *_edge_getOtherVert(CCGEdge *e, CCGVert *vQ) -{ - if (vQ == e->v0) { - return e->v1; - } - else { - return e->v0; - } -} - -static void *_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize) -{ - int levelBase = ccg_edgebase(lvl); - return &EDGE_getLevelData(e)[dataSize * (levelBase + x)]; -} -static float *_edge_getNo(CCGEdge *e, int lvl, int x, int dataSize, int normalDataOffset) -{ - int levelBase = ccg_edgebase(lvl); - return (float *) &EDGE_getLevelData(e)[dataSize * (levelBase + x) + normalDataOffset]; -} static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSize) { int levelBase = ccg_edgebase(lvl); @@ -690,18 +203,6 @@ static void _edge_unlinkMarkAndFree(CCGEdge *e, CCGSubSurf *ss) _edge_free(e, ss); } -static float EDGE_getSharpness(CCGEdge *e, int lvl) -{ - if (!lvl) - return e->crease; - else if (!e->crease) - return 0.0f; - else if (e->crease - lvl < 0.0f) - return 0.0f; - else - return e->crease - lvl; -} - static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, CCGSubSurf *ss) { int maxGridSize = ccg_gridsize(ss->subdivLevels); @@ -733,102 +234,6 @@ static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int return f; } - -BLI_INLINE void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize) -{ - int maxGridSize = ccg_gridsize(levels); - int spacing = ccg_spacing(levels, lvl); - byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize)); - return &gridBase[dataSize * x * spacing]; -} -BLI_INLINE void *_face_getIENo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize, int normalDataOffset) -{ - int maxGridSize = ccg_gridsize(levels); - int spacing = ccg_spacing(levels, lvl); - byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize)); - return &gridBase[dataSize * x * spacing + normalDataOffset]; -} -BLI_INLINE void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize) -{ - int maxGridSize = ccg_gridsize(levels); - int spacing = ccg_spacing(levels, lvl); - byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize)); - return &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing)]; -} -BLI_INLINE float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) -{ - int maxGridSize = ccg_gridsize(levels); - int spacing = ccg_spacing(levels, lvl); - byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize)); - return (float *) &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing) + normalDataOffset]; -} -BLI_INLINE int _face_getVertIndex(CCGFace *f, CCGVert *v) -{ - int i; - for (i = 0; i < f->numVerts; i++) - if (FACE_getVerts(f)[i] == v) - return i; - return -1; -} -BLI_INLINE int _face_getEdgeIndex(CCGFace *f, CCGEdge *e) -{ - int i; - for (i = 0; i < f->numVerts; i++) - if (FACE_getEdges(f)[i] == e) - return i; - return -1; -} -BLI_INLINE void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int f_ed_idx, int lvl, int eX, int eY, int levels, int dataSize) -{ - int maxGridSize = ccg_gridsize(levels); - int spacing = ccg_spacing(levels, lvl); - int x, y, cx, cy; - - BLI_assert(f_ed_idx == _face_getEdgeIndex(f, e)); - - eX = eX * spacing; - eY = eY * spacing; - if (e->v0 != FACE_getVerts(f)[f_ed_idx]) { - eX = (maxGridSize * 2 - 1) - 1 - eX; - } - y = maxGridSize - 1 - eX; - x = maxGridSize - 1 - eY; - if (x < 0) { - f_ed_idx = (f_ed_idx + f->numVerts - 1) % f->numVerts; - cx = y; - cy = -x; - } - else if (y < 0) { - f_ed_idx = (f_ed_idx + 1) % f->numVerts; - cx = -y; - cy = x; - } - else { - cx = x; - cy = y; - } - return _face_getIFCo(f, levels, f_ed_idx, cx, cy, levels, dataSize); -} -static float *_face_getIFNoEdge(CCGFace *f, CCGEdge *e, int f_ed_idx, int lvl, int eX, int eY, int levels, int dataSize, int normalDataOffset) -{ - return (float *) ((byte *) _face_getIFCoEdge(f, e, f_ed_idx, lvl, eX, eY, levels, dataSize) + normalDataOffset); -} -static void _face_calcIFNo(CCGFace *f, int lvl, int S, int x, int y, float no[3], int levels, int dataSize) -{ - float *a = _face_getIFCo(f, lvl, S, x + 0, y + 0, levels, dataSize); - float *b = _face_getIFCo(f, lvl, S, x + 1, y + 0, levels, dataSize); - float *c = _face_getIFCo(f, lvl, S, x + 1, y + 1, levels, dataSize); - float *d = _face_getIFCo(f, lvl, S, x + 0, y + 1, levels, dataSize); - float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2]; - float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2]; - - no[0] = b_dY * a_cZ - b_dZ * a_cY; - no[1] = b_dZ * a_cX - b_dX * a_cZ; - no[2] = b_dX * a_cY - b_dY * a_cX; - - Normalize(no); -} - static void _face_free(CCGFace *f, CCGSubSurf *ss) { CCGSUBSURF_free(ss, f); @@ -849,7 +254,7 @@ static void _face_unlinkMarkAndFree(CCGFace *f, CCGSubSurf *ss) CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) { if (!allocatorIFC) { - allocatorIFC = _getStandardAllocatorIFC(); + allocatorIFC = ccg_getStandardAllocatorIFC(); allocator = NULL; } @@ -862,9 +267,9 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a ss->allocatorIFC = *allocatorIFC; ss->allocator = allocator; - ss->vMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); - ss->eMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); - ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator); ss->meshIFC = *ifc; @@ -904,9 +309,9 @@ void ccgSubSurf_free(CCGSubSurf *ss) CCGAllocatorHDL allocator = ss->allocator; if (ss->syncState) { - _ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_free, ss); - _ehash_free(ss->oldEMap, (EHEntryFreeFP) _edge_free, ss); - _ehash_free(ss->oldVMap, (EHEntryFreeFP) _vert_free, ss); + ccg_ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_free, ss); + ccg_ehash_free(ss->oldEMap, (EHEntryFreeFP) _edge_free, ss); + ccg_ehash_free(ss->oldVMap, (EHEntryFreeFP) _vert_free, ss); MEM_freeN(ss->tempVerts); MEM_freeN(ss->tempEdges); @@ -916,9 +321,9 @@ void ccgSubSurf_free(CCGSubSurf *ss) CCGSUBSURF_free(ss, ss->q); if (ss->defaultEdgeUserData) CCGSUBSURF_free(ss, ss->defaultEdgeUserData); - _ehash_free(ss->fMap, (EHEntryFreeFP) _face_free, ss); - _ehash_free(ss->eMap, (EHEntryFreeFP) _edge_free, ss); - _ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss); + ccg_ehash_free(ss->fMap, (EHEntryFreeFP) _face_free, ss); + ccg_ehash_free(ss->eMap, (EHEntryFreeFP) _edge_free, ss); + ccg_ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss); CCGSUBSURF_free(ss, ss); @@ -963,12 +368,12 @@ CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels) else if (subdivisionLevels != ss->subdivLevels) { ss->numGrids = 0; ss->subdivLevels = subdivisionLevels; - _ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss); - _ehash_free(ss->eMap, (EHEntryFreeFP) _edge_free, ss); - _ehash_free(ss->fMap, (EHEntryFreeFP) _face_free, ss); - ss->vMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); - ss->eMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); - ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); + ccg_ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss); + ccg_ehash_free(ss->eMap, (EHEntryFreeFP) _edge_free, ss); + ccg_ehash_free(ss->fMap, (EHEntryFreeFP) _face_free, ss); + ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator); } return eCCGError_None; @@ -1051,9 +456,9 @@ CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss) ss->oldEMap = ss->eMap; ss->oldFMap = ss->fMap; - ss->vMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); - ss->eMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); - ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator); ss->numGrids = 0; @@ -1086,7 +491,7 @@ CCGError ccgSubSurf_syncVertDel(CCGSubSurf *ss, CCGVertHDL vHDL) } else { void **prevp; - CCGVert *v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp); + CCGVert *v = ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp); if (!v || v->numFaces || v->numEdges) { return eCCGError_InvalidValue; @@ -1107,7 +512,7 @@ CCGError ccgSubSurf_syncEdgeDel(CCGSubSurf *ss, CCGEdgeHDL eHDL) } else { void **prevp; - CCGEdge *e = _ehash_lookupWithPrev(ss->eMap, eHDL, &prevp); + CCGEdge *e = ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp); if (!e || e->numFaces) { return eCCGError_InvalidValue; @@ -1128,7 +533,7 @@ CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL) } else { void **prevp; - CCGFace *f = _ehash_lookupWithPrev(ss->fMap, fHDL, &prevp); + CCGFace *f = ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp); if (!f) { return eCCGError_InvalidValue; @@ -1149,19 +554,19 @@ CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertDa short seamflag = (seam) ? Vert_eSeam : 0; if (ss->syncState == eSyncState_Partial) { - v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp); + v = ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp); if (!v) { v = _vert_new(vHDL, ss); - VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss); - _ehash_insert(ss->vMap, (EHEntry *) v); + VertDataCopy(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss); + ccg_ehash_insert(ss->vMap, (EHEntry *) v); v->flags = Vert_eEffected | seamflag; } - else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize), ss) || + else if (!VertDataEqual(vertData, ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), ss) || ((v->flags & Vert_eSeam) != seamflag)) { int i, j; - VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss); + VertDataCopy(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss); v->flags = Vert_eEffected | seamflag; for (i = 0; i < v->numEdges; i++) { @@ -1182,24 +587,24 @@ CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertDa return eCCGError_InvalidSyncState; } - v = _ehash_lookupWithPrev(ss->oldVMap, vHDL, &prevp); + v = ccg_ehash_lookupWithPrev(ss->oldVMap, vHDL, &prevp); if (!v) { v = _vert_new(vHDL, ss); - VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss); - _ehash_insert(ss->vMap, (EHEntry *) v); + VertDataCopy(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss); + ccg_ehash_insert(ss->vMap, (EHEntry *) v); v->flags = Vert_eEffected | seamflag; } - else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize), ss) || + else if (!VertDataEqual(vertData, ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), ss) || ((v->flags & Vert_eSeam) != seamflag)) { *prevp = v->next; - _ehash_insert(ss->vMap, (EHEntry *) v); - VertDataCopy(_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss); + ccg_ehash_insert(ss->vMap, (EHEntry *) v); + VertDataCopy(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss); v->flags = Vert_eEffected | Vert_eChanged | seamflag; } else { *prevp = v->next; - _ehash_insert(ss->vMap, (EHEntry *) v); + ccg_ehash_insert(ss->vMap, (EHEntry *) v); v->flags = 0; } } @@ -1214,10 +619,10 @@ CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0 CCGEdge *e = NULL, *eNew; if (ss->syncState == eSyncState_Partial) { - e = _ehash_lookupWithPrev(ss->eMap, eHDL, &prevp); + e = ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp); if (!e || e->v0->vHDL != e_vHDL0 || e->v1->vHDL != e_vHDL1 || crease != e->crease) { - CCGVert *v0 = _ehash_lookup(ss->vMap, e_vHDL0); - CCGVert *v1 = _ehash_lookup(ss->vMap, e_vHDL1); + CCGVert *v0 = ccg_ehash_lookup(ss->vMap, e_vHDL0); + CCGVert *v1 = ccg_ehash_lookup(ss->vMap, e_vHDL1); eNew = _edge_new(eHDL, v0, v1, crease, ss); @@ -1228,7 +633,7 @@ CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0 _edge_unlinkMarkAndFree(e, ss); } else { - _ehash_insert(ss->eMap, (EHEntry *) eNew); + ccg_ehash_insert(ss->eMap, (EHEntry *) eNew); } eNew->v0->flags |= Vert_eEffected; @@ -1243,18 +648,18 @@ CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0 return eCCGError_InvalidSyncState; } - e = _ehash_lookupWithPrev(ss->oldEMap, eHDL, &prevp); + e = ccg_ehash_lookupWithPrev(ss->oldEMap, eHDL, &prevp); if (!e || e->v0->vHDL != e_vHDL0 || e->v1->vHDL != e_vHDL1 || e->crease != crease) { - CCGVert *v0 = _ehash_lookup(ss->vMap, e_vHDL0); - CCGVert *v1 = _ehash_lookup(ss->vMap, e_vHDL1); + CCGVert *v0 = ccg_ehash_lookup(ss->vMap, e_vHDL0); + CCGVert *v1 = ccg_ehash_lookup(ss->vMap, e_vHDL1); e = _edge_new(eHDL, v0, v1, crease, ss); - _ehash_insert(ss->eMap, (EHEntry *) e); + ccg_ehash_insert(ss->eMap, (EHEntry *) e); e->v0->flags |= Vert_eEffected; e->v1->flags |= Vert_eEffected; } else { *prevp = e->next; - _ehash_insert(ss->eMap, (EHEntry *) e); + ccg_ehash_insert(ss->eMap, (EHEntry *) e); e->flags = 0; if ((e->v0->flags | e->v1->flags) & Vert_eChanged) { e->v0->flags |= Vert_eEffected; @@ -1280,10 +685,10 @@ CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGV } if (ss->syncState == eSyncState_Partial) { - f = _ehash_lookupWithPrev(ss->fMap, fHDL, &prevp); + f = ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp); for (k = 0; k < numVerts; k++) { - ss->tempVerts[k] = _ehash_lookup(ss->vMap, vHDLs[k]); + ss->tempVerts[k] = ccg_ehash_lookup(ss->vMap, vHDLs[k]); } for (k = 0; k < numVerts; k++) { ss->tempEdges[k] = _vert_findEdgeTo(ss->tempVerts[k], ss->tempVerts[(k + 1) % numVerts]); @@ -1311,7 +716,7 @@ CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGV } else { ss->numGrids += numVerts; - _ehash_insert(ss->fMap, (EHEntry *) fNew); + ccg_ehash_insert(ss->fMap, (EHEntry *) fNew); } for (k = 0; k < numVerts; k++) @@ -1326,10 +731,10 @@ CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGV return eCCGError_InvalidSyncState; } - f = _ehash_lookupWithPrev(ss->oldFMap, fHDL, &prevp); + f = ccg_ehash_lookupWithPrev(ss->oldFMap, fHDL, &prevp); for (k = 0; k < numVerts; k++) { - ss->tempVerts[k] = _ehash_lookup(ss->vMap, vHDLs[k]); + ss->tempVerts[k] = ccg_ehash_lookup(ss->vMap, vHDLs[k]); if (!ss->tempVerts[k]) return eCCGError_InvalidValue; @@ -1340,7 +745,7 @@ CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGV if (!ss->tempEdges[k]) { if (ss->allowEdgeCreation) { CCGEdge *e = ss->tempEdges[k] = _edge_new((CCGEdgeHDL) - 1, ss->tempVerts[k], ss->tempVerts[(k + 1) % numVerts], ss->defaultCreaseValue, ss); - _ehash_insert(ss->eMap, (EHEntry *) e); + ccg_ehash_insert(ss->eMap, (EHEntry *) e); e->v0->flags |= Vert_eEffected; e->v1->flags |= Vert_eEffected; if (ss->meshIFC.edgeUserSize) { @@ -1364,7 +769,7 @@ CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGV if (!f || topologyChanged) { f = _face_new(fHDL, ss->tempVerts, ss->tempEdges, numVerts, ss); - _ehash_insert(ss->fMap, (EHEntry *) f); + ccg_ehash_insert(ss->fMap, (EHEntry *) f); ss->numGrids += numVerts; for (k = 0; k < numVerts; k++) @@ -1372,7 +777,7 @@ CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGV } else { *prevp = f->next; - _ehash_insert(ss->fMap, (EHEntry *) f); + ccg_ehash_insert(ss->fMap, (EHEntry *) f); f->flags = 0; ss->numGrids += f->numVerts; @@ -1390,6 +795,11 @@ CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGV return eCCGError_None; } +static void ccgSubSurf__sync(CCGSubSurf *ss) +{ + ccgSubSurf__sync_legacy(ss); +} + CCGError ccgSubSurf_processSync(CCGSubSurf *ss) { if (ss->syncState == eSyncState_Partial) { @@ -1398,9 +808,9 @@ CCGError ccgSubSurf_processSync(CCGSubSurf *ss) ccgSubSurf__sync(ss); } else if (ss->syncState) { - _ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_unlinkMarkAndFree, ss); - _ehash_free(ss->oldEMap, (EHEntryFreeFP) _edge_unlinkMarkAndFree, ss); - _ehash_free(ss->oldVMap, (EHEntryFreeFP) _vert_free, ss); + ccg_ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_unlinkMarkAndFree, ss); + ccg_ehash_free(ss->oldEMap, (EHEntryFreeFP) _edge_unlinkMarkAndFree, ss); + ccg_ehash_free(ss->oldVMap, (EHEntryFreeFP) _vert_free, ss); MEM_freeN(ss->tempEdges); MEM_freeN(ss->tempVerts); @@ -1421,1018 +831,16 @@ CCGError ccgSubSurf_processSync(CCGSubSurf *ss) return eCCGError_None; } -#define VERT_getCo(v, lvl) _vert_getCo(v, lvl, vertDataSize) -#define VERT_getNo(e, lvl) _vert_getNo(v, lvl, vertDataSize, normalDataOffset) -#define EDGE_getCo(e, lvl, x) _edge_getCo(e, lvl, x, vertDataSize) -#define EDGE_getNo(e, lvl, x) _edge_getNo(e, lvl, x, vertDataSize, normalDataOffset) -#define FACE_getIFNo(f, lvl, S, x, y) _face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset) -#define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize) -#define FACE_getIENo(f, lvl, S, x) _face_getIENo(f, lvl, S, x, subdivLevels, vertDataSize, normalDataOffset) - -static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss, - CCGVert **effectedV, CCGEdge **effectedE, CCGFace **effectedF, - int numEffectedV, int numEffectedE, int numEffectedF) -{ - int i, ptrIdx; - int subdivLevels = ss->subdivLevels; - int lvl = ss->subdivLevels; - int edgeSize = ccg_edgesize(lvl); - int gridSize = ccg_gridsize(lvl); - int normalDataOffset = ss->normalDataOffset; - int vertDataSize = ss->meshIFC.vertDataSize; - -#pragma omp parallel for private(ptrIdx) if (numEffectedF * edgeSize * edgeSize * 4 >= CCG_OMP_LIMIT) - for (ptrIdx = 0; ptrIdx < numEffectedF; ptrIdx++) { - CCGFace *f = (CCGFace *) effectedF[ptrIdx]; - int S, x, y; - float no[3]; +void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces) +{ + CCGFace **array; + int i, num; - for (S = 0; S < f->numVerts; S++) { - for (y = 0; y < gridSize - 1; y++) { - for (x = 0; x < gridSize - 1; x++) { - NormZero(FACE_getIFNo(f, lvl, S, x, y)); - } - } - - if (FACE_getEdges(f)[(S - 1 + f->numVerts) % f->numVerts]->flags & Edge_eEffected) { - for (x = 0; x < gridSize - 1; x++) { - NormZero(FACE_getIFNo(f, lvl, S, x, gridSize - 1)); - } - } - if (FACE_getEdges(f)[S]->flags & Edge_eEffected) { - for (y = 0; y < gridSize - 1; y++) { - NormZero(FACE_getIFNo(f, lvl, S, gridSize - 1, y)); - } - } - if (FACE_getVerts(f)[S]->flags & Vert_eEffected) { - NormZero(FACE_getIFNo(f, lvl, S, gridSize - 1, gridSize - 1)); - } - } - - for (S = 0; S < f->numVerts; S++) { - int yLimit = !(FACE_getEdges(f)[(S - 1 + f->numVerts) % f->numVerts]->flags & Edge_eEffected); - int xLimit = !(FACE_getEdges(f)[S]->flags & Edge_eEffected); - int yLimitNext = xLimit; - int xLimitPrev = yLimit; - - for (y = 0; y < gridSize - 1; y++) { - for (x = 0; x < gridSize - 1; x++) { - int xPlusOk = (!xLimit || x < gridSize - 2); - int yPlusOk = (!yLimit || y < gridSize - 2); - - FACE_calcIFNo(f, lvl, S, x, y, no); - - NormAdd(FACE_getIFNo(f, lvl, S, x + 0, y + 0), no); - if (xPlusOk) - NormAdd(FACE_getIFNo(f, lvl, S, x + 1, y + 0), no); - if (yPlusOk) - NormAdd(FACE_getIFNo(f, lvl, S, x + 0, y + 1), no); - if (xPlusOk && yPlusOk) { - if (x < gridSize - 2 || y < gridSize - 2 || FACE_getVerts(f)[S]->flags & Vert_eEffected) { - NormAdd(FACE_getIFNo(f, lvl, S, x + 1, y + 1), no); - } - } - - if (x == 0 && y == 0) { - int K; - - if (!yLimitNext || 1 < gridSize - 1) - NormAdd(FACE_getIFNo(f, lvl, (S + 1) % f->numVerts, 0, 1), no); - if (!xLimitPrev || 1 < gridSize - 1) - NormAdd(FACE_getIFNo(f, lvl, (S - 1 + f->numVerts) % f->numVerts, 1, 0), no); - - for (K = 0; K < f->numVerts; K++) { - if (K != S) { - NormAdd(FACE_getIFNo(f, lvl, K, 0, 0), no); - } - } - } - else if (y == 0) { - NormAdd(FACE_getIFNo(f, lvl, (S + 1) % f->numVerts, 0, x), no); - if (!yLimitNext || x < gridSize - 2) - NormAdd(FACE_getIFNo(f, lvl, (S + 1) % f->numVerts, 0, x + 1), no); - } - else if (x == 0) { - NormAdd(FACE_getIFNo(f, lvl, (S - 1 + f->numVerts) % f->numVerts, y, 0), no); - if (!xLimitPrev || y < gridSize - 2) - NormAdd(FACE_getIFNo(f, lvl, (S - 1 + f->numVerts) % f->numVerts, y + 1, 0), no); - } - } - } - } - } - /* XXX can I reduce the number of normalisations here? */ - for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) { - CCGVert *v = (CCGVert *) effectedV[ptrIdx]; - float *no = VERT_getNo(v, lvl); - - NormZero(no); - - for (i = 0; i < v->numFaces; i++) { - CCGFace *f = v->faces[i]; - NormAdd(no, FACE_getIFNo(f, lvl, _face_getVertIndex(f, v), gridSize - 1, gridSize - 1)); - } - - if (UNLIKELY(v->numFaces == 0)) { - NormCopy(no, VERT_getCo(v, lvl)); - } - - Normalize(no); - - for (i = 0; i < v->numFaces; i++) { - CCGFace *f = v->faces[i]; - NormCopy(FACE_getIFNo(f, lvl, _face_getVertIndex(f, v), gridSize - 1, gridSize - 1), no); - } - } - for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) { - CCGEdge *e = (CCGEdge *) effectedE[ptrIdx]; - - if (e->numFaces) { - CCGFace *fLast = e->faces[e->numFaces - 1]; - int x; - - for (i = 0; i < e->numFaces - 1; i++) { - CCGFace *f = e->faces[i]; - const int f_ed_idx = _face_getEdgeIndex(f, e); - const int f_ed_idx_last = _face_getEdgeIndex(fLast, e); - - for (x = 1; x < edgeSize - 1; x++) { - NormAdd(_face_getIFNoEdge(fLast, e, f_ed_idx_last, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset), - _face_getIFNoEdge(f, e, f_ed_idx, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset)); - } - } - - for (i = 0; i < e->numFaces - 1; i++) { - CCGFace *f = e->faces[i]; - const int f_ed_idx = _face_getEdgeIndex(f, e); - const int f_ed_idx_last = _face_getEdgeIndex(fLast, e); - - for (x = 1; x < edgeSize - 1; x++) { - NormCopy(_face_getIFNoEdge(f, e, f_ed_idx, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset), - _face_getIFNoEdge(fLast, e, f_ed_idx_last, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset)); - } - } - } - } - -#pragma omp parallel for private(ptrIdx) if (numEffectedF * edgeSize * edgeSize * 4 >= CCG_OMP_LIMIT) - for (ptrIdx = 0; ptrIdx < numEffectedF; ptrIdx++) { - CCGFace *f = (CCGFace *) effectedF[ptrIdx]; - int S, x, y; - - for (S = 0; S < f->numVerts; S++) { - NormCopy(FACE_getIFNo(f, lvl, (S + 1) % f->numVerts, 0, gridSize - 1), - FACE_getIFNo(f, lvl, S, gridSize - 1, 0)); - } - - for (S = 0; S < f->numVerts; S++) { - for (y = 0; y < gridSize; y++) { - for (x = 0; x < gridSize; x++) { - float *no = FACE_getIFNo(f, lvl, S, x, y); - Normalize(no); - } - } - - VertDataCopy((float *)((byte *)FACE_getCenterData(f) + normalDataOffset), - FACE_getIFNo(f, lvl, S, 0, 0), ss); - - for (x = 1; x < gridSize - 1; x++) - NormCopy(FACE_getIENo(f, lvl, S, x), - FACE_getIFNo(f, lvl, S, x, 0)); - } - } - - for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) { - CCGEdge *e = (CCGEdge *) effectedE[ptrIdx]; - - if (e->numFaces) { - CCGFace *f = e->faces[0]; - int x; - const int f_ed_idx = _face_getEdgeIndex(f, e); - - for (x = 0; x < edgeSize; x++) - NormCopy(EDGE_getNo(e, lvl, x), - _face_getIFNoEdge(f, e, f_ed_idx, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset)); - } - else { - /* set to zero here otherwise the normals are uninitialized memory - * render: tests/animation/knight.blend with valgrind. - * we could be more clever and interpolate vertex normals but these are - * most likely not used so just zero out. */ - int x; - - for (x = 0; x < edgeSize; x++) { - float *no = EDGE_getNo(e, lvl, x); - NormCopy(no, EDGE_getCo(e, lvl, x)); - Normalize(no); - } - } - } -} -#undef FACE_getIFNo - -#define FACE_getIECo(f, lvl, S, x) _face_getIECo(f, lvl, S, x, subdivLevels, vertDataSize) -#define FACE_getIFCo(f, lvl, S, x, y) _face_getIFCo(f, lvl, S, x, y, subdivLevels, vertDataSize) - -static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, - CCGVert **effectedV, CCGEdge **effectedE, CCGFace **effectedF, - int numEffectedV, int numEffectedE, int numEffectedF, int curLvl) -{ - int subdivLevels = ss->subdivLevels; - int edgeSize = ccg_edgesize(curLvl); - int gridSize = ccg_gridsize(curLvl); - int nextLvl = curLvl + 1; - int ptrIdx, cornerIdx, i; - int vertDataSize = ss->meshIFC.vertDataSize; - float *q = ss->q, *r = ss->r; - -#pragma omp parallel for private(ptrIdx) if (numEffectedF * edgeSize * edgeSize * 4 >= CCG_OMP_LIMIT) - for (ptrIdx = 0; ptrIdx < numEffectedF; ptrIdx++) { - CCGFace *f = (CCGFace *) effectedF[ptrIdx]; - int S, x, y; - - /* interior face midpoints - * - old interior face points - */ - for (S = 0; S < f->numVerts; S++) { - for (y = 0; y < gridSize - 1; y++) { - for (x = 0; x < gridSize - 1; x++) { - int fx = 1 + 2 * x; - int fy = 1 + 2 * y; - const float *co0 = FACE_getIFCo(f, curLvl, S, x + 0, y + 0); - const float *co1 = FACE_getIFCo(f, curLvl, S, x + 1, y + 0); - const float *co2 = FACE_getIFCo(f, curLvl, S, x + 1, y + 1); - const float *co3 = FACE_getIFCo(f, curLvl, S, x + 0, y + 1); - float *co = FACE_getIFCo(f, nextLvl, S, fx, fy); - - VertDataAvg4(co, co0, co1, co2, co3, ss); - } - } - } - - /* interior edge midpoints - * - old interior edge points - * - new interior face midpoints - */ - for (S = 0; S < f->numVerts; S++) { - for (x = 0; x < gridSize - 1; x++) { - int fx = x * 2 + 1; - const float *co0 = FACE_getIECo(f, curLvl, S, x + 0); - const float *co1 = FACE_getIECo(f, curLvl, S, x + 1); - const float *co2 = FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 1, fx); - const float *co3 = FACE_getIFCo(f, nextLvl, S, fx, 1); - float *co = FACE_getIECo(f, nextLvl, S, fx); - - VertDataAvg4(co, co0, co1, co2, co3, ss); - } - - /* interior face interior edge midpoints - * - old interior face points - * - new interior face midpoints - */ - - /* vertical */ - for (x = 1; x < gridSize - 1; x++) { - for (y = 0; y < gridSize - 1; y++) { - int fx = x * 2; - int fy = y * 2 + 1; - const float *co0 = FACE_getIFCo(f, curLvl, S, x, y + 0); - const float *co1 = FACE_getIFCo(f, curLvl, S, x, y + 1); - const float *co2 = FACE_getIFCo(f, nextLvl, S, fx - 1, fy); - const float *co3 = FACE_getIFCo(f, nextLvl, S, fx + 1, fy); - float *co = FACE_getIFCo(f, nextLvl, S, fx, fy); - - VertDataAvg4(co, co0, co1, co2, co3, ss); - } - } - - /* horizontal */ - for (y = 1; y < gridSize - 1; y++) { - for (x = 0; x < gridSize - 1; x++) { - int fx = x * 2 + 1; - int fy = y * 2; - const float *co0 = FACE_getIFCo(f, curLvl, S, x + 0, y); - const float *co1 = FACE_getIFCo(f, curLvl, S, x + 1, y); - const float *co2 = FACE_getIFCo(f, nextLvl, S, fx, fy - 1); - const float *co3 = FACE_getIFCo(f, nextLvl, S, fx, fy + 1); - float *co = FACE_getIFCo(f, nextLvl, S, fx, fy); - - VertDataAvg4(co, co0, co1, co2, co3, ss); - } - } - } - } - - /* exterior edge midpoints - * - old exterior edge points - * - new interior face midpoints - */ - for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) { - CCGEdge *e = (CCGEdge *) effectedE[ptrIdx]; - float sharpness = EDGE_getSharpness(e, curLvl); - int x, j; - - if (_edge_isBoundary(e) || sharpness > 1.0f) { - for (x = 0; x < edgeSize - 1; x++) { - int fx = x * 2 + 1; - const float *co0 = EDGE_getCo(e, curLvl, x + 0); - const float *co1 = EDGE_getCo(e, curLvl, x + 1); - float *co = EDGE_getCo(e, nextLvl, fx); - - VertDataCopy(co, co0, ss); - VertDataAdd(co, co1, ss); - VertDataMulN(co, 0.5f, ss); - } - } - else { - for (x = 0; x < edgeSize - 1; x++) { - int fx = x * 2 + 1; - const float *co0 = EDGE_getCo(e, curLvl, x + 0); - const float *co1 = EDGE_getCo(e, curLvl, x + 1); - float *co = EDGE_getCo(e, nextLvl, fx); - int numFaces = 0; - - VertDataCopy(q, co0, ss); - VertDataAdd(q, co1, ss); - - for (j = 0; j < e->numFaces; j++) { - CCGFace *f = e->faces[j]; - const int f_ed_idx = _face_getEdgeIndex(f, e); - VertDataAdd(q, _face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx, 1, subdivLevels, vertDataSize), ss); - numFaces++; - } - - VertDataMulN(q, 1.0f / (2.0f + numFaces), ss); - - VertDataCopy(r, co0, ss); - VertDataAdd(r, co1, ss); - VertDataMulN(r, 0.5f, ss); - - VertDataCopy(co, q, ss); - VertDataSub(r, q, ss); - VertDataMulN(r, sharpness, ss); - VertDataAdd(co, r, ss); - } - } - } - - /* exterior vertex shift - * - old vertex points (shifting) - * - old exterior edge points - * - new interior face midpoints - */ - for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) { - CCGVert *v = (CCGVert *) effectedV[ptrIdx]; - const float *co = VERT_getCo(v, curLvl); - float *nCo = VERT_getCo(v, nextLvl); - int sharpCount = 0, allSharp = 1; - float avgSharpness = 0.0; - int j, seam = VERT_seam(v), seamEdges = 0; - - for (j = 0; j < v->numEdges; j++) { - CCGEdge *e = v->edges[j]; - float sharpness = EDGE_getSharpness(e, curLvl); - - if (seam && _edge_isBoundary(e)) - seamEdges++; - - if (sharpness != 0.0f) { - sharpCount++; - avgSharpness += sharpness; - } - else { - allSharp = 0; - } - } - - if (sharpCount) { - avgSharpness /= sharpCount; - if (avgSharpness > 1.0f) { - avgSharpness = 1.0f; - } - } - - if (seamEdges < 2 || seamEdges != v->numEdges) - seam = 0; - - if (!v->numEdges || ss->meshIFC.simpleSubdiv) { - VertDataCopy(nCo, co, ss); - } - else if (_vert_isBoundary(v)) { - int numBoundary = 0; - - VertDataZero(r, ss); - for (j = 0; j < v->numEdges; j++) { - CCGEdge *e = v->edges[j]; - if (_edge_isBoundary(e)) { - VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss); - numBoundary++; - } - } - - VertDataCopy(nCo, co, ss); - VertDataMulN(nCo, 0.75f, ss); - VertDataMulN(r, 0.25f / numBoundary, ss); - VertDataAdd(nCo, r, ss); - } - else { - int cornerIdx = (1 + (1 << (curLvl))) - 2; - int numEdges = 0, numFaces = 0; - - VertDataZero(q, ss); - for (j = 0; j < v->numFaces; j++) { - CCGFace *f = v->faces[j]; - VertDataAdd(q, FACE_getIFCo(f, nextLvl, _face_getVertIndex(f, v), cornerIdx, cornerIdx), ss); - numFaces++; - } - VertDataMulN(q, 1.0f / numFaces, ss); - VertDataZero(r, ss); - for (j = 0; j < v->numEdges; j++) { - CCGEdge *e = v->edges[j]; - VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss); - numEdges++; - } - VertDataMulN(r, 1.0f / numEdges, ss); - - VertDataCopy(nCo, co, ss); - VertDataMulN(nCo, numEdges - 2.0f, ss); - VertDataAdd(nCo, q, ss); - VertDataAdd(nCo, r, ss); - VertDataMulN(nCo, 1.0f / numEdges, ss); - } - - if ((sharpCount > 1 && v->numFaces) || seam) { - VertDataZero(q, ss); - - if (seam) { - avgSharpness = 1.0f; - sharpCount = seamEdges; - allSharp = 1; - } - - for (j = 0; j < v->numEdges; j++) { - CCGEdge *e = v->edges[j]; - float sharpness = EDGE_getSharpness(e, curLvl); - - if (seam) { - if (_edge_isBoundary(e)) - VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss); - } - else if (sharpness != 0.0f) { - VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss); - } - } - - VertDataMulN(q, (float) 1 / sharpCount, ss); - - if (sharpCount != 2 || allSharp) { - /* q = q + (co - q) * avgSharpness */ - VertDataCopy(r, co, ss); - VertDataSub(r, q, ss); - VertDataMulN(r, avgSharpness, ss); - VertDataAdd(q, r, ss); - } - - /* r = co * 0.75 + q * 0.25 */ - VertDataCopy(r, co, ss); - VertDataMulN(r, 0.75f, ss); - VertDataMulN(q, 0.25f, ss); - VertDataAdd(r, q, ss); - - /* nCo = nCo + (r - nCo) * avgSharpness */ - VertDataSub(r, nCo, ss); - VertDataMulN(r, avgSharpness, ss); - VertDataAdd(nCo, r, ss); - } - } - - /* exterior edge interior shift - * - old exterior edge midpoints (shifting) - * - old exterior edge midpoints - * - new interior face midpoints - */ - for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) { - CCGEdge *e = (CCGEdge *) effectedE[ptrIdx]; - float sharpness = EDGE_getSharpness(e, curLvl); - int sharpCount = 0; - float avgSharpness = 0.0; - int x, j; - - if (sharpness != 0.0f) { - sharpCount = 2; - avgSharpness += sharpness; - - if (avgSharpness > 1.0f) { - avgSharpness = 1.0f; - } - } - else { - sharpCount = 0; - avgSharpness = 0; - } - - if (_edge_isBoundary(e)) { - for (x = 1; x < edgeSize - 1; x++) { - int fx = x * 2; - const float *co = EDGE_getCo(e, curLvl, x); - float *nCo = EDGE_getCo(e, nextLvl, fx); - - /* Average previous level's endpoints */ - VertDataCopy(r, EDGE_getCo(e, curLvl, x - 1), ss); - VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1), ss); - VertDataMulN(r, 0.5f, ss); - - /* nCo = nCo * 0.75 + r * 0.25 */ - VertDataCopy(nCo, co, ss); - VertDataMulN(nCo, 0.75f, ss); - VertDataMulN(r, 0.25f, ss); - VertDataAdd(nCo, r, ss); - } - } - else { - for (x = 1; x < edgeSize - 1; x++) { - int fx = x * 2; - const float *co = EDGE_getCo(e, curLvl, x); - float *nCo = EDGE_getCo(e, nextLvl, fx); - int numFaces = 0; - - VertDataZero(q, ss); - VertDataZero(r, ss); - VertDataAdd(r, EDGE_getCo(e, curLvl, x - 1), ss); - VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1), ss); - for (j = 0; j < e->numFaces; j++) { - CCGFace *f = e->faces[j]; - int f_ed_idx = _face_getEdgeIndex(f, e); - VertDataAdd(q, _face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx - 1, 1, subdivLevels, vertDataSize), ss); - VertDataAdd(q, _face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx + 1, 1, subdivLevels, vertDataSize), ss); - - VertDataAdd(r, _face_getIFCoEdge(f, e, f_ed_idx, curLvl, x, 1, subdivLevels, vertDataSize), ss); - numFaces++; - } - VertDataMulN(q, 1.0f / (numFaces * 2.0f), ss); - VertDataMulN(r, 1.0f / (2.0f + numFaces), ss); - - VertDataCopy(nCo, co, ss); - VertDataMulN(nCo, (float) numFaces, ss); - VertDataAdd(nCo, q, ss); - VertDataAdd(nCo, r, ss); - VertDataMulN(nCo, 1.0f / (2 + numFaces), ss); - - if (sharpCount == 2) { - VertDataCopy(q, co, ss); - VertDataMulN(q, 6.0f, ss); - VertDataAdd(q, EDGE_getCo(e, curLvl, x - 1), ss); - VertDataAdd(q, EDGE_getCo(e, curLvl, x + 1), ss); - VertDataMulN(q, 1 / 8.0f, ss); - - VertDataSub(q, nCo, ss); - VertDataMulN(q, avgSharpness, ss); - VertDataAdd(nCo, q, ss); - } - } - } - } - -#pragma omp parallel private(ptrIdx) if (numEffectedF * edgeSize * edgeSize * 4 >= CCG_OMP_LIMIT) - { - float *q, *r; - -#pragma omp critical - { - q = MEM_mallocN(ss->meshIFC.vertDataSize, "CCGSubsurf q"); - r = MEM_mallocN(ss->meshIFC.vertDataSize, "CCGSubsurf r"); - } - -#pragma omp for schedule(static) - for (ptrIdx = 0; ptrIdx < numEffectedF; ptrIdx++) { - CCGFace *f = (CCGFace *) effectedF[ptrIdx]; - int S, x, y; - - /* interior center point shift - * - old face center point (shifting) - * - old interior edge points - * - new interior face midpoints - */ - VertDataZero(q, ss); - for (S = 0; S < f->numVerts; S++) { - VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1), ss); - } - VertDataMulN(q, 1.0f / f->numVerts, ss); - VertDataZero(r, ss); - for (S = 0; S < f->numVerts; S++) { - VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1), ss); - } - VertDataMulN(r, 1.0f / f->numVerts, ss); - - VertDataMulN((float *)FACE_getCenterData(f), f->numVerts - 2.0f, ss); - VertDataAdd((float *)FACE_getCenterData(f), q, ss); - VertDataAdd((float *)FACE_getCenterData(f), r, ss); - VertDataMulN((float *)FACE_getCenterData(f), 1.0f / f->numVerts, ss); - - for (S = 0; S < f->numVerts; S++) { - /* interior face shift - * - old interior face point (shifting) - * - new interior edge midpoints - * - new interior face midpoints - */ - for (x = 1; x < gridSize - 1; x++) { - for (y = 1; y < gridSize - 1; y++) { - int fx = x * 2; - int fy = y * 2; - const float *co = FACE_getIFCo(f, curLvl, S, x, y); - float *nCo = FACE_getIFCo(f, nextLvl, S, fx, fy); - - VertDataAvg4(q, - FACE_getIFCo(f, nextLvl, S, fx - 1, fy - 1), - FACE_getIFCo(f, nextLvl, S, fx + 1, fy - 1), - FACE_getIFCo(f, nextLvl, S, fx + 1, fy + 1), - FACE_getIFCo(f, nextLvl, S, fx - 1, fy + 1), - ss); - - VertDataAvg4(r, - FACE_getIFCo(f, nextLvl, S, fx - 1, fy + 0), - FACE_getIFCo(f, nextLvl, S, fx + 1, fy + 0), - FACE_getIFCo(f, nextLvl, S, fx + 0, fy - 1), - FACE_getIFCo(f, nextLvl, S, fx + 0, fy + 1), - ss); - - VertDataCopy(nCo, co, ss); - VertDataSub(nCo, q, ss); - VertDataMulN(nCo, 0.25f, ss); - VertDataAdd(nCo, r, ss); - } - } - - /* interior edge interior shift - * - old interior edge point (shifting) - * - new interior edge midpoints - * - new interior face midpoints - */ - for (x = 1; x < gridSize - 1; x++) { - int fx = x * 2; - const float *co = FACE_getIECo(f, curLvl, S, x); - float *nCo = FACE_getIECo(f, nextLvl, S, fx); - - VertDataAvg4(q, - FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 1, fx - 1), - FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 1, fx + 1), - FACE_getIFCo(f, nextLvl, S, fx + 1, +1), - FACE_getIFCo(f, nextLvl, S, fx - 1, +1), ss); - - VertDataAvg4(r, - FACE_getIECo(f, nextLvl, S, fx - 1), - FACE_getIECo(f, nextLvl, S, fx + 1), - FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 1, fx), - FACE_getIFCo(f, nextLvl, S, fx, 1), - ss); - - VertDataCopy(nCo, co, ss); - VertDataSub(nCo, q, ss); - VertDataMulN(nCo, 0.25f, ss); - VertDataAdd(nCo, r, ss); - } - } - } - -#pragma omp critical - { - MEM_freeN(q); - MEM_freeN(r); - } - } - - /* copy down */ - edgeSize = ccg_edgesize(nextLvl); - gridSize = ccg_gridsize(nextLvl); - cornerIdx = gridSize - 1; - -#pragma omp parallel for private(i) if (numEffectedF * edgeSize * edgeSize * 4 >= CCG_OMP_LIMIT) - for (i = 0; i < numEffectedE; i++) { - CCGEdge *e = effectedE[i]; - VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl), ss); - VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize - 1), VERT_getCo(e->v1, nextLvl), ss); - } - -#pragma omp parallel for private(i) if (numEffectedF * edgeSize * edgeSize * 4 >= CCG_OMP_LIMIT) - for (i = 0; i < numEffectedF; i++) { - CCGFace *f = effectedF[i]; - int S, x; - - for (S = 0; S < f->numVerts; S++) { - CCGEdge *e = FACE_getEdges(f)[S]; - CCGEdge *prevE = FACE_getEdges(f)[(S + f->numVerts - 1) % f->numVerts]; - - VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), (float *)FACE_getCenterData(f), ss); - VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), (float *)FACE_getCenterData(f), ss); - VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], nextLvl), ss); - VertDataCopy(FACE_getIECo(f, nextLvl, S, cornerIdx), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, cornerIdx), ss); - for (x = 1; x < gridSize - 1; x++) { - float *co = FACE_getIECo(f, nextLvl, S, x); - VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, 0), co, ss); - VertDataCopy(FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 0, x), co, ss); - } - for (x = 0; x < gridSize - 1; x++) { - int eI = gridSize - 1 - x; - VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize), ss); - VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize), ss); - } - } - } -} - - -static void ccgSubSurf__sync(CCGSubSurf *ss) -{ - CCGVert **effectedV; - CCGEdge **effectedE; - CCGFace **effectedF; - int numEffectedV, numEffectedE, numEffectedF; - int subdivLevels = ss->subdivLevels; - int vertDataSize = ss->meshIFC.vertDataSize; - int i, j, ptrIdx, S; - int curLvl, nextLvl; - void *q = ss->q, *r = ss->r; - - effectedV = MEM_mallocN(sizeof(*effectedV) * ss->vMap->numEntries, "CCGSubsurf effectedV"); - effectedE = MEM_mallocN(sizeof(*effectedE) * ss->eMap->numEntries, "CCGSubsurf effectedE"); - effectedF = MEM_mallocN(sizeof(*effectedF) * ss->fMap->numEntries, "CCGSubsurf effectedF"); - numEffectedV = numEffectedE = numEffectedF = 0; - for (i = 0; i < ss->vMap->curSize; i++) { - CCGVert *v = (CCGVert *) ss->vMap->buckets[i]; - for (; v; v = v->next) { - if (v->flags & Vert_eEffected) { - effectedV[numEffectedV++] = v; - - for (j = 0; j < v->numEdges; j++) { - CCGEdge *e = v->edges[j]; - if (!(e->flags & Edge_eEffected)) { - effectedE[numEffectedE++] = e; - e->flags |= Edge_eEffected; - } - } - - for (j = 0; j < v->numFaces; j++) { - CCGFace *f = v->faces[j]; - if (!(f->flags & Face_eEffected)) { - effectedF[numEffectedF++] = f; - f->flags |= Face_eEffected; - } - } - } - } - } - - curLvl = 0; - nextLvl = curLvl + 1; - - for (ptrIdx = 0; ptrIdx < numEffectedF; ptrIdx++) { - CCGFace *f = effectedF[ptrIdx]; - void *co = FACE_getCenterData(f); - VertDataZero(co, ss); - for (i = 0; i < f->numVerts; i++) { - VertDataAdd(co, VERT_getCo(FACE_getVerts(f)[i], curLvl), ss); - } - VertDataMulN(co, 1.0f / f->numVerts, ss); - - f->flags = 0; - } - for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) { - CCGEdge *e = effectedE[ptrIdx]; - void *co = EDGE_getCo(e, nextLvl, 1); - float sharpness = EDGE_getSharpness(e, curLvl); - - if (_edge_isBoundary(e) || sharpness >= 1.0f) { - VertDataCopy(co, VERT_getCo(e->v0, curLvl), ss); - VertDataAdd(co, VERT_getCo(e->v1, curLvl), ss); - VertDataMulN(co, 0.5f, ss); - } - else { - int numFaces = 0; - VertDataCopy(q, VERT_getCo(e->v0, curLvl), ss); - VertDataAdd(q, VERT_getCo(e->v1, curLvl), ss); - for (i = 0; i < e->numFaces; i++) { - CCGFace *f = e->faces[i]; - VertDataAdd(q, (float *)FACE_getCenterData(f), ss); - numFaces++; - } - VertDataMulN(q, 1.0f / (2.0f + numFaces), ss); - - VertDataCopy(r, VERT_getCo(e->v0, curLvl), ss); - VertDataAdd(r, VERT_getCo(e->v1, curLvl), ss); - VertDataMulN(r, 0.5f, ss); - - VertDataCopy(co, q, ss); - VertDataSub(r, q, ss); - VertDataMulN(r, sharpness, ss); - VertDataAdd(co, r, ss); - } - - /* edge flags cleared later */ - } - for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) { - CCGVert *v = effectedV[ptrIdx]; - void *co = VERT_getCo(v, curLvl); - void *nCo = VERT_getCo(v, nextLvl); - int sharpCount = 0, allSharp = 1; - float avgSharpness = 0.0; - int seam = VERT_seam(v), seamEdges = 0; - - for (i = 0; i < v->numEdges; i++) { - CCGEdge *e = v->edges[i]; - float sharpness = EDGE_getSharpness(e, curLvl); - - if (seam && _edge_isBoundary(e)) - seamEdges++; - - if (sharpness != 0.0f) { - sharpCount++; - avgSharpness += sharpness; - } - else { - allSharp = 0; - } - } - - if (sharpCount) { - avgSharpness /= sharpCount; - if (avgSharpness > 1.0f) { - avgSharpness = 1.0f; - } - } - - if (seamEdges < 2 || seamEdges != v->numEdges) - seam = 0; - - if (!v->numEdges || ss->meshIFC.simpleSubdiv) { - VertDataCopy(nCo, co, ss); - } - else if (_vert_isBoundary(v)) { - int numBoundary = 0; - - VertDataZero(r, ss); - for (i = 0; i < v->numEdges; i++) { - CCGEdge *e = v->edges[i]; - if (_edge_isBoundary(e)) { - VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl), ss); - numBoundary++; - } - } - VertDataCopy(nCo, co, ss); - VertDataMulN(nCo, 0.75f, ss); - VertDataMulN(r, 0.25f / numBoundary, ss); - VertDataAdd(nCo, r, ss); - } - else { - int numEdges = 0, numFaces = 0; - - VertDataZero(q, ss); - for (i = 0; i < v->numFaces; i++) { - CCGFace *f = v->faces[i]; - VertDataAdd(q, (float *)FACE_getCenterData(f), ss); - numFaces++; - } - VertDataMulN(q, 1.0f / numFaces, ss); - VertDataZero(r, ss); - for (i = 0; i < v->numEdges; i++) { - CCGEdge *e = v->edges[i]; - VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl), ss); - numEdges++; - } - VertDataMulN(r, 1.0f / numEdges, ss); - - VertDataCopy(nCo, co, ss); - VertDataMulN(nCo, numEdges - 2.0f, ss); - VertDataAdd(nCo, q, ss); - VertDataAdd(nCo, r, ss); - VertDataMulN(nCo, 1.0f / numEdges, ss); - } - - if (sharpCount > 1 || seam) { - VertDataZero(q, ss); - - if (seam) { - avgSharpness = 1.0f; - sharpCount = seamEdges; - allSharp = 1; - } - - for (i = 0; i < v->numEdges; i++) { - CCGEdge *e = v->edges[i]; - float sharpness = EDGE_getSharpness(e, curLvl); - - if (seam) { - if (_edge_isBoundary(e)) { - CCGVert *oV = _edge_getOtherVert(e, v); - VertDataAdd(q, VERT_getCo(oV, curLvl), ss); - } - } - else if (sharpness != 0.0f) { - CCGVert *oV = _edge_getOtherVert(e, v); - VertDataAdd(q, VERT_getCo(oV, curLvl), ss); - } - } - - VertDataMulN(q, (float) 1 / sharpCount, ss); - - if (sharpCount != 2 || allSharp) { - /* q = q + (co - q) * avgSharpness */ - VertDataCopy(r, co, ss); - VertDataSub(r, q, ss); - VertDataMulN(r, avgSharpness, ss); - VertDataAdd(q, r, ss); - } - - /* r = co * 0.75 + q * 0.25 */ - VertDataCopy(r, co, ss); - VertDataMulN(r, 0.75f, ss); - VertDataMulN(q, 0.25f, ss); - VertDataAdd(r, q, ss); - - /* nCo = nCo + (r - nCo) * avgSharpness */ - VertDataSub(r, nCo, ss); - VertDataMulN(r, avgSharpness, ss); - VertDataAdd(nCo, r, ss); - } - - /* vert flags cleared later */ - } - - if (ss->useAgeCounts) { - for (i = 0; i < numEffectedV; i++) { - CCGVert *v = effectedV[i]; - byte *userData = ccgSubSurf_getVertUserData(ss, v); - *((int *) &userData[ss->vertUserAgeOffset]) = ss->currentAge; - } - - for (i = 0; i < numEffectedE; i++) { - CCGEdge *e = effectedE[i]; - byte *userData = ccgSubSurf_getEdgeUserData(ss, e); - *((int *) &userData[ss->edgeUserAgeOffset]) = ss->currentAge; - } - - for (i = 0; i < numEffectedF; i++) { - CCGFace *f = effectedF[i]; - byte *userData = ccgSubSurf_getFaceUserData(ss, f); - *((int *) &userData[ss->faceUserAgeOffset]) = ss->currentAge; - } - } - - for (i = 0; i < numEffectedE; i++) { - CCGEdge *e = effectedE[i]; - VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl), ss); - VertDataCopy(EDGE_getCo(e, nextLvl, 2), VERT_getCo(e->v1, nextLvl), ss); - } - for (i = 0; i < numEffectedF; i++) { - CCGFace *f = effectedF[i]; - for (S = 0; S < f->numVerts; S++) { - CCGEdge *e = FACE_getEdges(f)[S]; - CCGEdge *prevE = FACE_getEdges(f)[(S + f->numVerts - 1) % f->numVerts]; - - VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), (float *)FACE_getCenterData(f), ss); - VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), (float *)FACE_getCenterData(f), ss); - VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 1), VERT_getCo(FACE_getVerts(f)[S], nextLvl), ss); - VertDataCopy(FACE_getIECo(f, nextLvl, S, 1), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, 1), ss); - - VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 0), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize), ss); - VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 1), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize), ss); - } - } - - for (curLvl = 1; curLvl < subdivLevels; curLvl++) { - ccgSubSurf__calcSubdivLevel(ss, - effectedV, effectedE, effectedF, - numEffectedV, numEffectedE, numEffectedF, curLvl); - } - - if (ss->calcVertNormals) - ccgSubSurf__calcVertNormals(ss, - effectedV, effectedE, effectedF, - numEffectedV, numEffectedE, numEffectedF); - - for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) { - CCGVert *v = effectedV[ptrIdx]; - v->flags = 0; - } - for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) { - CCGEdge *e = effectedE[ptrIdx]; - e->flags = 0; - } - - MEM_freeN(effectedF); - MEM_freeN(effectedE); - MEM_freeN(effectedV); -} - -static void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces) -{ - CCGFace **array; - int i, num; - - if (*faces == NULL) { - array = MEM_mallocN(sizeof(*array) * ss->fMap->numEntries, "CCGSubsurf allFaces"); - num = 0; - for (i = 0; i < ss->fMap->curSize; i++) { - CCGFace *f = (CCGFace *) ss->fMap->buckets[i]; + if (*faces == NULL) { + array = MEM_mallocN(sizeof(*array) * ss->fMap->numEntries, "CCGSubsurf allFaces"); + num = 0; + for (i = 0; i < ss->fMap->curSize; i++) { + CCGFace *f = (CCGFace *) ss->fMap->buckets[i]; for (; f; f = f->next) array[num++] = f; @@ -2447,7 +855,7 @@ static void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces } } -static void ccgSubSurf__effectedFaceNeighbours(CCGSubSurf *ss, CCGFace **faces, int numFaces, CCGVert ***verts, int *numVerts, CCGEdge ***edges, int *numEdges) +void ccgSubSurf__effectedFaceNeighbours(CCGSubSurf *ss, CCGFace **faces, int numFaces, CCGVert ***verts, int *numVerts, CCGEdge ***edges, int *numEdges) { CCGVert **arrayV; CCGEdge **arrayE; @@ -2716,75 +1124,6 @@ CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, in return eCCGError_None; } -/* update normals for specified faces */ -CCGError ccgSubSurf_updateNormals(CCGSubSurf *ss, CCGFace **effectedF, int numEffectedF) -{ - CCGVert **effectedV; - CCGEdge **effectedE; - int i, numEffectedV, numEffectedE, freeF; - - ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF); - ccgSubSurf__effectedFaceNeighbours(ss, effectedF, numEffectedF, - &effectedV, &numEffectedV, &effectedE, &numEffectedE); - - if (ss->calcVertNormals) - ccgSubSurf__calcVertNormals(ss, - effectedV, effectedE, effectedF, - numEffectedV, numEffectedE, numEffectedF); - - for (i = 0; i < numEffectedV; i++) - effectedV[i]->flags = 0; - for (i = 0; i < numEffectedE; i++) - effectedE[i]->flags = 0; - for (i = 0; i < numEffectedF; i++) - effectedF[i]->flags = 0; - - MEM_freeN(effectedE); - MEM_freeN(effectedV); - if (freeF) MEM_freeN(effectedF); - - return eCCGError_None; -} - -/* compute subdivision levels from a given starting point, used by - * multires subdivide/propagate, by filling in coordinates at a - * certain level, and then subdividing that up to the highest level */ -CCGError ccgSubSurf_updateLevels(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF) -{ - CCGVert **effectedV; - CCGEdge **effectedE; - int numEffectedV, numEffectedE, freeF, i; - int curLvl, subdivLevels = ss->subdivLevels; - - ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF); - ccgSubSurf__effectedFaceNeighbours(ss, effectedF, numEffectedF, - &effectedV, &numEffectedV, &effectedE, &numEffectedE); - - for (curLvl = lvl; curLvl < subdivLevels; curLvl++) { - ccgSubSurf__calcSubdivLevel(ss, - effectedV, effectedE, effectedF, - numEffectedV, numEffectedE, numEffectedF, curLvl); - } - - for (i = 0; i < numEffectedV; i++) - effectedV[i]->flags = 0; - for (i = 0; i < numEffectedE; i++) - effectedE[i]->flags = 0; - for (i = 0; i < numEffectedF; i++) - effectedF[i]->flags = 0; - - MEM_freeN(effectedE); - MEM_freeN(effectedV); - if (freeF) MEM_freeN(effectedF); - - return eCCGError_None; -} - -#undef VERT_getCo -#undef EDGE_getCo -#undef FACE_getIECo -#undef FACE_getIFCo - /*** External API accessor functions ***/ int ccgSubSurf_getNumVerts(const CCGSubSurf *ss) @@ -2802,15 +1141,15 @@ int ccgSubSurf_getNumFaces(const CCGSubSurf *ss) CCGVert *ccgSubSurf_getVert(CCGSubSurf *ss, CCGVertHDL v) { - return (CCGVert *) _ehash_lookup(ss->vMap, v); + return (CCGVert *) ccg_ehash_lookup(ss->vMap, v); } CCGEdge *ccgSubSurf_getEdge(CCGSubSurf *ss, CCGEdgeHDL e) { - return (CCGEdge *) _ehash_lookup(ss->eMap, e); + return (CCGEdge *) ccg_ehash_lookup(ss->eMap, e); } CCGFace *ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f) { - return (CCGFace *) _ehash_lookup(ss->fMap, f); + return (CCGFace *) ccg_ehash_lookup(ss->fMap, f); } int ccgSubSurf_getSubdivisionLevels(const CCGSubSurf *ss) @@ -2905,7 +1244,7 @@ void *ccgSubSurf_getVertLevelData(CCGSubSurf *ss, CCGVert *v, int level) return NULL; } else { - return _vert_getCo(v, level, ss->meshIFC.vertDataSize); + return ccg_vert_getCo(v, level, ss->meshIFC.vertDataSize); } } @@ -2965,7 +1304,7 @@ void *ccgSubSurf_getEdgeLevelData(CCGSubSurf *ss, CCGEdge *e, int x, int level) return NULL; } else { - return _edge_getCo(e, level, x, ss->meshIFC.vertDataSize); + return ccg_edge_getCo(e, level, x, ss->meshIFC.vertDataSize); } } float ccgSubSurf_getEdgeCrease(CCGEdge *e) @@ -3037,7 +1376,7 @@ void *ccgSubSurf_getFaceGridEdgeDataArray(CCGSubSurf *ss, CCGFace *f, int gridIn } void *ccgSubSurf_getFaceGridEdgeData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x) { - return _face_getIECo(f, ss->subdivLevels, gridIndex, x, ss->subdivLevels, ss->meshIFC.vertDataSize); + return ccg_face_getIECo(f, ss->subdivLevels, gridIndex, x, ss->subdivLevels, ss->meshIFC.vertDataSize); } void *ccgSubSurf_getFaceGridDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex) { @@ -3045,61 +1384,61 @@ void *ccgSubSurf_getFaceGridDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex) } void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y) { - return _face_getIFCo(f, ss->subdivLevels, gridIndex, x, y, ss->subdivLevels, ss->meshIFC.vertDataSize); + return ccg_face_getIFCo(f, ss->subdivLevels, gridIndex, x, y, ss->subdivLevels, ss->meshIFC.vertDataSize); } /*** External API iterator functions ***/ void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter) { - _ehashIterator_init(ss->vMap, viter); + ccg_ehashIterator_init(ss->vMap, viter); } void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter) { - _ehashIterator_init(ss->eMap, eiter); + ccg_ehashIterator_init(ss->eMap, eiter); } void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter) { - _ehashIterator_init(ss->fMap, fiter); + ccg_ehashIterator_init(ss->fMap, fiter); } CCGVert *ccgVertIterator_getCurrent(CCGVertIterator *vi) { - return (CCGVert *) _ehashIterator_getCurrent((EHashIterator *) vi); + return (CCGVert *) ccg_ehashIterator_getCurrent((EHashIterator *) vi); } int ccgVertIterator_isStopped(CCGVertIterator *vi) { - return _ehashIterator_isStopped((EHashIterator *) vi); + return ccg_ehashIterator_isStopped((EHashIterator *) vi); } void ccgVertIterator_next(CCGVertIterator *vi) { - _ehashIterator_next((EHashIterator *) vi); + ccg_ehashIterator_next((EHashIterator *) vi); } CCGEdge *ccgEdgeIterator_getCurrent(CCGEdgeIterator *vi) { - return (CCGEdge *) _ehashIterator_getCurrent((EHashIterator *) vi); + return (CCGEdge *) ccg_ehashIterator_getCurrent((EHashIterator *) vi); } int ccgEdgeIterator_isStopped(CCGEdgeIterator *vi) { - return _ehashIterator_isStopped((EHashIterator *) vi); + return ccg_ehashIterator_isStopped((EHashIterator *) vi); } void ccgEdgeIterator_next(CCGEdgeIterator *vi) { - _ehashIterator_next((EHashIterator *) vi); + ccg_ehashIterator_next((EHashIterator *) vi); } CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *vi) { - return (CCGFace *) _ehashIterator_getCurrent((EHashIterator *) vi); + return (CCGFace *) ccg_ehashIterator_getCurrent((EHashIterator *) vi); } int ccgFaceIterator_isStopped(CCGFaceIterator *vi) { - return _ehashIterator_isStopped((EHashIterator *) vi); + return ccg_ehashIterator_isStopped((EHashIterator *) vi); } void ccgFaceIterator_next(CCGFaceIterator *vi) { - _ehashIterator_next((EHashIterator *) vi); + ccg_ehashIterator_next((EHashIterator *) vi); } /*** Extern API final vert/edge/face interface ***/ -- cgit v1.2.3