Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-07-20 16:05:16 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-07-20 23:29:25 +0300
commitccc3c2dbda36f00e74064e993d7e98bf8ab32a58 (patch)
tree43ac1a879558089e1cb7d6b7b7252fb91f711e76 /source/blender/blenkernel/intern/CCGSubSurf.c
parent6190d75b5a8854f04c05cbd14a27837763fa5b95 (diff)
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.
Diffstat (limited to 'source/blender/blenkernel/intern/CCGSubSurf.c')
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c1827
1 files changed, 83 insertions, 1744 deletions
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
+#include "GL/glew.h"
/***/
-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;
-}
-
-/***/
-
-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,1009 +831,7 @@ 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];
-
- 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)
+void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces)
{
CCGFace **array;
int i, num;
@@ -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 ***/