1
/* $Id: CCGSubSurf.c,v 1.23 2005/08/20 09:16:09 zuster Exp $ */
8
#include "CCGSubSurf.h"
12
typedef unsigned char byte;
16
static int kHashSizes[] = {
17
1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209,
18
16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169,
19
4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459
22
typedef struct _EHEntry EHEntry;
27
typedef struct _EHash {
29
int numEntries, curSize, curSizeIdx;
31
CCGAllocatorIFC allocatorIFC;
32
CCGAllocatorHDL allocator;
35
#define EHASH_alloc(eh, nb) ((eh)->allocatorIFC.alloc((eh)->allocator, nb))
36
#define EHASH_free(eh, ptr) ((eh)->allocatorIFC.free((eh)->allocator, ptr))
38
#define EHASH_hash(eh, item) (((unsigned long) (item))%((unsigned int) (eh)->curSize))
40
static EHash *_ehash_new(int estimatedNumEntries, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) {
41
EHash *eh = allocatorIFC->alloc(allocator, sizeof(*eh));
42
eh->allocatorIFC = *allocatorIFC;
43
eh->allocator = allocator;
46
while (kHashSizes[eh->curSizeIdx]<estimatedNumEntries)
48
eh->curSize = kHashSizes[eh->curSizeIdx];
49
eh->buckets = EHASH_alloc(eh, eh->curSize*sizeof(*eh->buckets));
50
memset(eh->buckets, 0, eh->curSize*sizeof(*eh->buckets));
54
typedef void (*EHEntryFreeFP)(EHEntry *, void *);
55
static void _ehash_free(EHash *eh, EHEntryFreeFP freeEntry, void *userData) {
56
int numBuckets = eh->curSize;
58
while (numBuckets--) {
59
EHEntry *entry = eh->buckets[numBuckets];
62
EHEntry *next = entry->next;
64
freeEntry(entry, userData);
70
EHASH_free(eh, eh->buckets);
74
static void _ehash_insert(EHash *eh, EHEntry *entry) {
75
int numBuckets = eh->curSize;
76
int hash = EHASH_hash(eh, entry->key);
77
entry->next = eh->buckets[hash];
78
eh->buckets[hash] = entry;
81
if (eh->numEntries > (numBuckets*3)) {
82
EHEntry **oldBuckets = eh->buckets;
83
eh->curSize = kHashSizes[++eh->curSizeIdx];
85
eh->buckets = EHASH_alloc(eh, eh->curSize*sizeof(*eh->buckets));
86
memset(eh->buckets, 0, eh->curSize*sizeof(*eh->buckets));
88
while (numBuckets--) {
89
for (entry = oldBuckets[numBuckets]; entry;) {
90
EHEntry *next = entry->next;
92
hash = EHASH_hash(eh, entry->key);
93
entry->next = eh->buckets[hash];
94
eh->buckets[hash] = entry;
100
EHASH_free(eh, oldBuckets);
104
static void *_ehash_lookupWithPrev(EHash *eh, void *key, void ***prevp_r) {
105
int hash = EHASH_hash(eh, key);
106
void **prevp = (void**) &eh->buckets[hash];
109
for (; (entry = *prevp); prevp = (void**) &entry->next) {
110
if (entry->key==key) {
111
*prevp_r = (void**) prevp;
119
static void *_ehash_lookup(EHash *eh, void *key) {
120
int hash = EHASH_hash(eh, key);
123
for (entry = eh->buckets[hash]; entry; entry = entry->next)
132
typedef struct _EHashIterator {
138
static EHashIterator *_ehashIterator_new(EHash *eh) {
139
EHashIterator *ehi = EHASH_alloc(eh, sizeof(*ehi));
141
ehi->curEntry = NULL;
143
while (!ehi->curEntry) {
145
if (ehi->curBucket==ehi->eh->curSize)
147
ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
151
static void _ehashIterator_free(EHashIterator *ehi) {
152
EHASH_free(ehi->eh, ehi);
155
static void *_ehashIterator_getCurrent(EHashIterator *ehi) {
156
return ehi->curEntry;
159
static void _ehashIterator_next(EHashIterator *ehi) {
161
ehi->curEntry = ehi->curEntry->next;
162
while (!ehi->curEntry) {
164
if (ehi->curBucket==ehi->eh->curSize)
166
ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
170
static int _ehashIterator_isStopped(EHashIterator *ehi) {
171
return !ehi->curEntry;
176
static void *_stdAllocator_alloc(CCGAllocatorHDL a, int numBytes) {
177
return malloc(numBytes);
179
static void *_stdAllocator_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
180
return realloc(ptr, newSize);
182
static void _stdAllocator_free(CCGAllocatorHDL a, void *ptr) {
186
static CCGAllocatorIFC *_getStandardAllocatorIFC(void) {
187
static CCGAllocatorIFC ifc;
189
ifc.alloc = _stdAllocator_alloc;
190
ifc.realloc = _stdAllocator_realloc;
191
ifc.free = _stdAllocator_free;
199
static int VertDataEqual(float *a, float *b) {
200
return a[0]==b[0] && a[1]==b[1] && a[2]==b[2];
202
#define VertDataZero(av) { float *a = (float*) av; a[0] = a[1] = a[2] = 0.0f; }
203
#define VertDataCopy(av, bv) { float *a = (float*) av, *b = (float*) bv; a[0] =b[0]; a[1] =b[1]; a[2] =b[2]; }
204
#define VertDataAdd(av, bv) { float *a = (float*) av, *b = (float*) bv; a[0]+=b[0]; a[1]+=b[1]; a[2]+=b[2]; }
205
#define VertDataSub(av, bv) { float *a = (float*) av, *b = (float*) bv; a[0]-=b[0]; a[1]-=b[1]; a[2]-=b[2]; }
206
#define VertDataMulN(av, n) { float *a = (float*) av; a[0]*=n; a[1]*=n; a[2]*=n; }
207
#define VertDataAvg4(tv, av, bv, cv, dv) \
209
float *t = (float*) tv, *a = (float*) av, *b = (float*) bv, *c = (float*) cv, *d = (float*) dv; \
210
t[0] = (a[0]+b[0]+c[0]+d[0])*.25; \
211
t[1] = (a[1]+b[1]+c[1]+d[1])*.25; \
212
t[2] = (a[2]+b[2]+c[2]+d[2])*.25; \
214
#define NormZero(av) { float *a = (float*) av; a[0] = a[1] = a[2] = 0.0f; }
215
#define NormCopy(av, bv) { float *a = (float*) av, *b = (float*) bv; a[0] =b[0]; a[1] =b[1]; a[2] =b[2]; }
216
#define NormAdd(av, bv) { float *a = (float*) av, *b = (float*) bv; a[0]+=b[0]; a[1]+=b[1]; a[2]+=b[2]; }
219
static int _edge_isBoundary(CCGEdge *e);
224
Vert_eEffected= (1<<0),
225
Vert_eChanged= (1<<1),
228
Edge_eEffected= (1<<0),
231
Face_eEffected= (1<<0),
235
CCGVert *next; /* EHData.next */
236
CCGVertHDL vHDL; /* EHData.key */
238
short numEdges, numFaces, flags, pad;
245
#define VERT_getLevelData(v) ((byte*) &(v)[1])
248
CCGEdge *next; /* EHData.next */
249
CCGEdgeHDL eHDL; /* EHData.key */
251
short numFaces, flags;
260
#define EDGE_getLevelData(e) ((byte*) &(e)[1])
263
CCGFace *next; /* EHData.next */
264
CCGFaceHDL fHDL; /* EHData.key */
266
short numVerts, flags, pad1, pad2;
274
#define FACE_getVerts(f) ((CCGVert**) &(f)[1])
275
#define FACE_getEdges(f) ((CCGEdge**) &(FACE_getVerts(f)[(f)->numVerts]))
276
#define FACE_getCenterData(f) ((byte*) &(FACE_getEdges(f)[(f)->numVerts]))
287
EHash *vMap; /* map of CCGVertHDL -> Vert */
288
EHash *eMap; /* map of CCGEdgeHDL -> Edge */
289
EHash *fMap; /* map of CCGFaceHDL -> Face */
293
CCGAllocatorIFC allocatorIFC;
294
CCGAllocatorHDL allocator;
298
int allowEdgeCreation;
299
float defaultCreaseValue;
300
void *defaultEdgeUserData;
304
// data for calc vert normals
306
int normalDataOffset;
308
// data for age'ing (to debug sync)
311
int vertUserAgeOffset;
312
int edgeUserAgeOffset;
313
int faceUserAgeOffset;
315
// data used during syncing
318
EHash *oldVMap, *oldEMap, *oldFMap;
324
#define CCGSUBSURF_alloc(ss, nb) ((ss)->allocatorIFC.alloc((ss)->allocator, nb))
325
#define CCGSUBSURF_realloc(ss, ptr, nb, ob) ((ss)->allocatorIFC.realloc((ss)->allocator, ptr, nb, ob))
326
#define CCGSUBSURF_free(ss, ptr) ((ss)->allocatorIFC.free((ss)->allocator, ptr))
330
static CCGVert *_vert_new(CCGVertHDL vHDL, int levels, int dataSize, CCGSubSurf *ss) {
331
CCGVert *v = CCGSUBSURF_alloc(ss, sizeof(CCGVert) + ss->meshIFC.vertDataSize * (ss->subdivLevels+1) + ss->meshIFC.vertUserSize);
337
v->numEdges = v->numFaces = 0;
340
userData = ccgSubSurf_getVertUserData(ss, v);
341
memset(userData, 0, ss->meshIFC.vertUserSize);
342
if (ss->useAgeCounts) *((int*) &userData[ss->vertUserAgeOffset]) = ss->currentAge;
346
static void _vert_remEdge(CCGVert *v, CCGEdge *e, CCGSubSurf *ss) {
348
for (i=0; i<v->numEdges; i++) {
349
if (v->edges[i]==e) {
350
v->edges[i] = v->edges[--v->numEdges];
355
static void _vert_remFace(CCGVert *v, CCGFace *f, CCGSubSurf *ss) {
357
for (i=0; i<v->numFaces; i++) {
358
if (v->faces[i]==f) {
359
v->faces[i] = v->faces[--v->numFaces];
364
static void _vert_addEdge(CCGVert *v, CCGEdge *e, CCGSubSurf *ss) {
365
v->edges = CCGSUBSURF_realloc(ss, v->edges, (v->numEdges+1)*sizeof(*v->edges), v->numEdges*sizeof(*v->edges));
366
v->edges[v->numEdges++] = e;
368
static void _vert_addFace(CCGVert *v, CCGFace *f, CCGSubSurf *ss) {
369
v->faces = CCGSUBSURF_realloc(ss, v->faces, (v->numFaces+1)*sizeof(*v->faces), v->numFaces*sizeof(*v->faces));
370
v->faces[v->numFaces++] = f;
372
static CCGEdge *_vert_findEdgeTo(CCGVert *v, CCGVert *vQ) {
374
for (i=0; i<v->numEdges; i++) {
375
CCGEdge *e = v->edges[v->numEdges-1-i]; // XXX, note reverse
376
if ( (e->v0==v && e->v1==vQ) ||
377
(e->v1==v && e->v0==vQ))
382
static int _vert_isBoundary(CCGVert *v) {
384
for (i=0; i<v->numEdges; i++)
385
if (_edge_isBoundary(v->edges[i]))
390
static void *_vert_getCo(CCGVert *v, int lvl, int dataSize) {
391
return &VERT_getLevelData(v)[lvl*dataSize];
393
static float *_vert_getNo(CCGVert *v, int lvl, int dataSize, int normalDataOffset) {
394
return (float*) &VERT_getLevelData(v)[lvl*dataSize + normalDataOffset];
397
static void _vert_free(CCGVert *v, CCGSubSurf *ss) {
398
CCGSUBSURF_free(ss, v->edges);
399
CCGSUBSURF_free(ss, v->faces);
400
CCGSUBSURF_free(ss, v);
405
static CCGEdge *_edge_new(CCGEdgeHDL eHDL, CCGVert *v0, CCGVert *v1, float crease, int levels, int dataSize, CCGSubSurf *ss) {
406
CCGEdge *e = CCGSUBSURF_alloc(ss, sizeof(CCGEdge) + ss->meshIFC.vertDataSize *((ss->subdivLevels+1) + (1<<(ss->subdivLevels+1))-1) + ss->meshIFC.edgeUserSize);
416
_vert_addEdge(v0, e, ss);
417
_vert_addEdge(v1, e, ss);
419
userData = ccgSubSurf_getEdgeUserData(ss, e);
420
memset(userData, 0, ss->meshIFC.edgeUserSize);
421
if (ss->useAgeCounts) *((int*) &userData[ss->edgeUserAgeOffset]) = ss->currentAge;
425
static void _edge_remFace(CCGEdge *e, CCGFace *f, CCGSubSurf *ss) {
427
for (i=0; i<e->numFaces; i++) {
428
if (e->faces[i]==f) {
429
e->faces[i] = e->faces[--e->numFaces];
434
static void _edge_addFace(CCGEdge *e, CCGFace *f, CCGSubSurf *ss) {
435
e->faces = CCGSUBSURF_realloc(ss, e->faces, (e->numFaces+1)*sizeof(*e->faces), e->numFaces*sizeof(*e->faces));
436
e->faces[e->numFaces++] = f;
438
static int _edge_isBoundary(CCGEdge *e) {
439
return e->numFaces<2;
442
static CCGVert *_edge_getOtherVert(CCGEdge *e, CCGVert *vQ) {
450
static void *_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize) {
451
int levelBase = lvl + (1<<lvl) - 1;
452
return &EDGE_getLevelData(e)[dataSize*(levelBase + x)];
454
static float *_edge_getNo(CCGEdge *e, int lvl, int x, int dataSize, int normalDataOffset) {
455
int levelBase = lvl + (1<<lvl) - 1;
456
return (float*) &EDGE_getLevelData(e)[dataSize*(levelBase + x) + normalDataOffset];
459
static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSize) {
460
int levelBase = lvl + (1<<lvl) - 1;
462
return &EDGE_getLevelData(e)[dataSize*(levelBase + x)];
464
return &EDGE_getLevelData(e)[dataSize*(levelBase + (1<<lvl) - x)];
468
static void _edge_free(CCGEdge *e, CCGSubSurf *ss) {
469
CCGSUBSURF_free(ss, e->faces);
470
CCGSUBSURF_free(ss, e);
472
static void _edge_unlinkMarkAndFree(CCGEdge *e, CCGSubSurf *ss) {
473
_vert_remEdge(e->v0, e, ss);
474
_vert_remEdge(e->v1, e, ss);
475
e->v0->flags |= Vert_eEffected;
476
e->v1->flags |= Vert_eEffected;
480
static float EDGE_getSharpness(CCGEdge *e, int lvl, CCGSubSurf *ss) {
481
float sharpness = e->crease;
494
static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, int levels, int dataSize, CCGSubSurf *ss) {
495
int maxGridSize = 1 + (1<<(ss->subdivLevels-1));
496
CCGFace *f = CCGSUBSURF_alloc(ss, sizeof(CCGFace) + sizeof(CCGVert*)*numVerts + sizeof(CCGEdge*)*numVerts + ss->meshIFC.vertDataSize *(1 + numVerts*maxGridSize + numVerts*maxGridSize*maxGridSize) + ss->meshIFC.faceUserSize);
500
f->numVerts = numVerts;
504
for (i=0; i<numVerts; i++) {
505
FACE_getVerts(f)[i] = verts[i];
506
FACE_getEdges(f)[i] = edges[i];
507
_vert_addFace(verts[i], f, ss);
508
_edge_addFace(edges[i], f, ss);
511
userData = ccgSubSurf_getFaceUserData(ss, f);
512
memset(userData, 0, ss->meshIFC.faceUserSize);
513
if (ss->useAgeCounts) *((int*) &userData[ss->faceUserAgeOffset]) = ss->currentAge;
518
static void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize) {
519
int maxGridSize = 1 + (1<<(levels-1));
520
int spacing = 1<<(levels-lvl);
521
byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize));
522
return &gridBase[dataSize*x*spacing];
524
static void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize) {
525
int maxGridSize = 1 + (1<<(levels-1));
526
int spacing = 1<<(levels-lvl);
527
byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize));
528
return &gridBase[dataSize*(maxGridSize + (y*maxGridSize + x)*spacing)];
530
static float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) {
531
int maxGridSize = 1 + (1<<(levels-1));
532
int spacing = 1<<(levels-lvl);
533
byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize));
534
return (float*) &gridBase[dataSize*(maxGridSize + (y*maxGridSize + x)*spacing) + normalDataOffset];
536
static int _face_getVertIndex(CCGFace *f, CCGVert *v) {
538
for (i=0; i<f->numVerts; i++)
539
if (FACE_getVerts(f)[i]==v)
543
static void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, int levels, int dataSize) {
544
int maxGridSize = 1 + (1<<(levels-1));
545
int spacing = 1<<(levels-lvl);
548
for (S=0; S<f->numVerts; S++)
549
if (FACE_getEdges(f)[S]==e)
554
if (e->v0!=FACE_getVerts(f)[S]) {
555
eX = (maxGridSize*2 - 1)-1 - eX;
557
y = maxGridSize - 1 - eX;
558
x = maxGridSize - 1 - eY;
560
S = (S+f->numVerts-1)%f->numVerts;
564
S = (S+1)%f->numVerts;
571
return _face_getIFCo(f, levels, S, cx, cy, levels, dataSize);
573
static float *_face_getIFNoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, int levels, int dataSize, int normalDataOffset) {
574
return (float*) ((byte*) _face_getIFCoEdge(f, e, lvl, eX, eY, levels, dataSize) + normalDataOffset);
576
void _face_calcIFNo(CCGFace *f, int lvl, int S, int x, int y, float *no, int levels, int dataSize) {
577
float *a = _face_getIFCo(f, lvl, S, x+0, y+0, levels, dataSize);
578
float *b = _face_getIFCo(f, lvl, S, x+1, y+0, levels, dataSize);
579
float *c = _face_getIFCo(f, lvl, S, x+1, y+1, levels, dataSize);
580
float *d = _face_getIFCo(f, lvl, S, x+0, y+1, levels, dataSize);
581
float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
582
float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
585
no[0] = b_dY*a_cZ - b_dZ*a_cY;
586
no[1] = b_dZ*a_cX - b_dX*a_cZ;
587
no[2] = b_dX*a_cY - b_dY*a_cX;
589
length = sqrt(no[0]*no[0] + no[1]*no[1] + no[2]*no[2]);
591
if (length>FLT_EPSILON) {
592
float invLength = 1.f/length;
602
static void _face_free(CCGFace *f, CCGSubSurf *ss) {
603
CCGSUBSURF_free(ss, f);
605
static void _face_unlinkMarkAndFree(CCGFace *f, CCGSubSurf *ss) {
607
for (j=0; j<f->numVerts; j++) {
608
_vert_remFace(FACE_getVerts(f)[j], f, ss);
609
_edge_remFace(FACE_getEdges(f)[j], f, ss);
610
FACE_getVerts(f)[j]->flags |= Vert_eEffected;
617
CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) {
619
allocatorIFC = _getStandardAllocatorIFC();
623
if (subdivLevels<1) {
626
CCGSubSurf *ss = allocatorIFC->alloc(allocator, sizeof(*ss));
628
ss->allocatorIFC = *allocatorIFC;
629
ss->allocator = allocator;
631
ss->vMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
632
ss->eMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
633
ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
637
ss->subdivLevels = subdivLevels;
639
ss->allowEdgeCreation = 0;
640
ss->defaultCreaseValue = 0;
641
ss->defaultEdgeUserData = NULL;
643
ss->useAgeCounts = 0;
644
ss->vertUserAgeOffset = ss->edgeUserAgeOffset = ss->faceUserAgeOffset = 0;
646
ss->calcVertNormals = 0;
647
ss->normalDataOffset = 0;
649
ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
650
ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
654
ss->syncState = eSyncState_None;
656
ss->oldVMap = ss->oldEMap = ss->oldFMap = NULL;
657
ss->lenTempArrays = 0;
658
ss->tempVerts = NULL;
659
ss->tempEdges = NULL;
665
void ccgSubSurf_free(CCGSubSurf *ss) {
666
CCGAllocatorIFC allocatorIFC = ss->allocatorIFC;
667
CCGAllocatorHDL allocator = ss->allocator;
670
_ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_free, ss);
671
_ehash_free(ss->oldEMap, (EHEntryFreeFP) _edge_free, ss);
672
_ehash_free(ss->oldVMap, (EHEntryFreeFP) _vert_free, ss);
674
CCGSUBSURF_free(ss, ss->tempVerts);
675
CCGSUBSURF_free(ss, ss->tempEdges);
678
CCGSUBSURF_free(ss, ss->r);
679
CCGSUBSURF_free(ss, ss->q);
680
if (ss->defaultEdgeUserData) CCGSUBSURF_free(ss, ss->defaultEdgeUserData);
682
_ehash_free(ss->fMap, (EHEntryFreeFP) _face_free, ss);
683
_ehash_free(ss->eMap, (EHEntryFreeFP) _edge_free, ss);
684
_ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss);
686
CCGSUBSURF_free(ss, ss);
688
if (allocatorIFC.release) {
689
allocatorIFC.release(allocator);
693
CCGError ccgSubSurf_setAllowEdgeCreation(CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue, void *defaultUserData) {
694
if (ss->defaultEdgeUserData) {
695
CCGSUBSURF_free(ss, ss->defaultEdgeUserData);
698
ss->allowEdgeCreation = !!allowEdgeCreation;
699
ss->defaultCreaseValue = defaultCreaseValue;
700
ss->defaultEdgeUserData = CCGSUBSURF_alloc(ss, ss->meshIFC.edgeUserSize);
702
if (defaultUserData) {
703
memcpy(ss->defaultEdgeUserData, defaultUserData, ss->meshIFC.edgeUserSize);
705
memset(ss->defaultEdgeUserData, 0, ss->meshIFC.edgeUserSize);
708
return eCCGError_None;
710
void ccgSubSurf_getAllowEdgeCreation(CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r, void *defaultUserData_r) {
711
if (allowEdgeCreation_r) *allowEdgeCreation_r = ss->allowEdgeCreation;
712
if (ss->allowEdgeCreation) {
713
if (defaultCreaseValue_r) *defaultCreaseValue_r = ss->defaultCreaseValue;
714
if (defaultUserData_r) memcpy(defaultUserData_r, ss->defaultEdgeUserData, ss->meshIFC.edgeUserSize);
718
CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels) {
719
if (subdivisionLevels<=0) {
720
return eCCGError_InvalidValue;
721
} else if (subdivisionLevels!=ss->subdivLevels) {
723
ss->subdivLevels = subdivisionLevels;
724
_ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss);
725
_ehash_free(ss->eMap, (EHEntryFreeFP) _edge_free, ss);
726
_ehash_free(ss->fMap, (EHEntryFreeFP) _face_free, ss);
727
ss->vMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
728
ss->eMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
729
ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
732
return eCCGError_None;
735
void ccgSubSurf_getUseAgeCounts(CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r)
737
*useAgeCounts_r = ss->useAgeCounts;
739
if (vertUserOffset_r) *vertUserOffset_r = ss->vertUserAgeOffset;
740
if (edgeUserOffset_r) *edgeUserOffset_r = ss->edgeUserAgeOffset;
741
if (faceUserOffset_r) *faceUserOffset_r = ss->faceUserAgeOffset;
744
CCGError ccgSubSurf_setUseAgeCounts(CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset) {
746
if ( (vertUserOffset+4>ss->meshIFC.vertUserSize) ||
747
(edgeUserOffset+4>ss->meshIFC.edgeUserSize) ||
748
(faceUserOffset+4>ss->meshIFC.faceUserSize)) {
749
return eCCGError_InvalidValue;
751
ss->useAgeCounts = 1;
752
ss->vertUserAgeOffset = vertUserOffset;
753
ss->edgeUserAgeOffset = edgeUserOffset;
754
ss->faceUserAgeOffset = faceUserOffset;
757
ss->useAgeCounts = 0;
758
ss->vertUserAgeOffset = ss->edgeUserAgeOffset = ss->faceUserAgeOffset = 0;
761
return eCCGError_None;
764
CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int normalDataOffset) {
765
if (useVertNormals) {
766
if (normalDataOffset<0 || normalDataOffset+12>ss->meshIFC.vertDataSize) {
767
return eCCGError_InvalidValue;
769
ss->calcVertNormals = 1;
770
ss->normalDataOffset = normalDataOffset;
773
ss->calcVertNormals = 0;
774
ss->normalDataOffset = 0;
777
return eCCGError_None;
782
CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss) {
783
if (ss->syncState!=eSyncState_None) {
784
return eCCGError_InvalidSyncState;
789
ss->oldVMap = ss->vMap;
790
ss->oldEMap = ss->eMap;
791
ss->oldFMap = ss->fMap;
793
ss->vMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
794
ss->eMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
795
ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
799
ss->lenTempArrays = 12;
800
ss->tempVerts = CCGSUBSURF_alloc(ss, sizeof(*ss->tempVerts)*ss->lenTempArrays);
801
ss->tempEdges = CCGSUBSURF_alloc(ss, sizeof(*ss->tempEdges)*ss->lenTempArrays);
803
ss->syncState = eSyncState_Vert;
805
return eCCGError_None;
808
CCGError ccgSubSurf_initPartialSync(CCGSubSurf *ss) {
809
if (ss->syncState!=eSyncState_None) {
810
return eCCGError_InvalidSyncState;
815
ss->syncState = eSyncState_Partial;
817
return eCCGError_None;
820
CCGError ccgSubSurf_syncVertDel(CCGSubSurf *ss, CCGVertHDL vHDL) {
821
if (ss->syncState!=eSyncState_Partial) {
822
return eCCGError_InvalidSyncState;
825
CCGVert *v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
827
if (!v || v->numFaces || v->numEdges) {
828
return eCCGError_InvalidValue;
835
return eCCGError_None;
838
CCGError ccgSubSurf_syncEdgeDel(CCGSubSurf *ss, CCGEdgeHDL eHDL) {
839
if (ss->syncState!=eSyncState_Partial) {
840
return eCCGError_InvalidSyncState;
843
CCGEdge *e = _ehash_lookupWithPrev(ss->eMap, eHDL, &prevp);
845
if (!e || e->numFaces) {
846
return eCCGError_InvalidValue;
849
_edge_unlinkMarkAndFree(e, ss);
853
return eCCGError_None;
856
CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL) {
857
if (ss->syncState!=eSyncState_Partial) {
858
return eCCGError_InvalidSyncState;
861
CCGFace *f = _ehash_lookupWithPrev(ss->fMap, fHDL, &prevp);
864
return eCCGError_InvalidValue;
867
_face_unlinkMarkAndFree(f, ss);
871
return eCCGError_None;
874
CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, CCGVert **v_r) {
878
if (ss->syncState==eSyncState_Partial) {
879
v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
881
v = _vert_new(vHDL, ss->subdivLevels, ss->meshIFC.vertDataSize, ss);
882
VertDataCopy(_vert_getCo(v,0,ss->meshIFC.vertDataSize), vertData);
883
_ehash_insert(ss->vMap, (EHEntry*) v);
884
v->flags = Vert_eEffected;
885
} else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize))) {
888
VertDataCopy(_vert_getCo(v,0,ss->meshIFC.vertDataSize), vertData);
889
v->flags = Vert_eEffected;
891
for (i=0; i<v->numEdges; i++) {
892
CCGEdge *e = v->edges[i];
893
e->v0->flags |= Vert_eEffected;
894
e->v1->flags |= Vert_eEffected;
896
for (i=0; i<v->numFaces; i++) {
897
CCGFace *f = v->faces[i];
898
for (j=0; j<f->numVerts; j++) {
899
FACE_getVerts(f)[j]->flags |= Vert_eEffected;
904
if (ss->syncState!=eSyncState_Vert) {
905
return eCCGError_InvalidSyncState;
908
v = _ehash_lookupWithPrev(ss->oldVMap, vHDL, &prevp);
910
v = _vert_new(vHDL, ss->subdivLevels, ss->meshIFC.vertDataSize, ss);
911
VertDataCopy(_vert_getCo(v,0,ss->meshIFC.vertDataSize), vertData);
912
_ehash_insert(ss->vMap, (EHEntry*) v);
913
v->flags = Vert_eEffected;
914
} else if (!VertDataEqual(vertData, _vert_getCo(v, 0, ss->meshIFC.vertDataSize))) {
916
_ehash_insert(ss->vMap, (EHEntry*) v);
917
VertDataCopy(_vert_getCo(v,0,ss->meshIFC.vertDataSize), vertData);
918
v->flags = Vert_eEffected|Vert_eChanged;
921
_ehash_insert(ss->vMap, (EHEntry*) v);
927
return eCCGError_None;
930
CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r) {
932
CCGEdge *e = NULL, *eNew;
934
if (ss->syncState==eSyncState_Partial) {
935
e = _ehash_lookupWithPrev(ss->eMap, eHDL, &prevp);
936
if (!e || e->v0->vHDL!=e_vHDL0 || e->v1->vHDL!=e_vHDL1 || crease!=e->crease) {
937
CCGVert *v0 = _ehash_lookup(ss->vMap, e_vHDL0);
938
CCGVert *v1 = _ehash_lookup(ss->vMap, e_vHDL1);
940
eNew = _edge_new(eHDL, v0, v1, crease, ss->subdivLevels, ss->meshIFC.vertDataSize, ss);
944
eNew->next = e->next;
946
_edge_unlinkMarkAndFree(e, ss);
948
_ehash_insert(ss->eMap, (EHEntry*) eNew);
951
eNew->v0->flags |= Vert_eEffected;
952
eNew->v1->flags |= Vert_eEffected;
955
if (ss->syncState==eSyncState_Vert) {
956
ss->syncState = eSyncState_Edge;
957
} else if (ss->syncState!=eSyncState_Edge) {
958
return eCCGError_InvalidSyncState;
961
e = _ehash_lookupWithPrev(ss->oldEMap, eHDL, &prevp);
962
if (!e || e->v0->vHDL!=e_vHDL0 || e->v1->vHDL!=e_vHDL1|| e->crease!=crease) {
963
CCGVert *v0 = _ehash_lookup(ss->vMap, e_vHDL0);
964
CCGVert *v1 = _ehash_lookup(ss->vMap, e_vHDL1);
965
e = _edge_new(eHDL, v0, v1, crease, ss->subdivLevels, ss->meshIFC.vertDataSize, ss);
966
_ehash_insert(ss->eMap, (EHEntry*) e);
967
e->v0->flags |= Vert_eEffected;
968
e->v1->flags |= Vert_eEffected;
971
_ehash_insert(ss->eMap, (EHEntry*) e);
973
if ((e->v0->flags|e->v1->flags)&Vert_eChanged) {
974
e->v0->flags |= Vert_eEffected;
975
e->v1->flags |= Vert_eEffected;
981
return eCCGError_None;
984
CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r) {
986
CCGFace *f = NULL, *fNew;
987
int j, k, topologyChanged = 0;
989
if (numVerts>ss->lenTempArrays) {
990
int oldLen = ss->lenTempArrays;
991
ss->lenTempArrays = (numVerts<ss->lenTempArrays*2)?ss->lenTempArrays*2:numVerts;
992
ss->tempVerts = CCGSUBSURF_realloc(ss, ss->tempVerts, sizeof(*ss->tempVerts)*ss->lenTempArrays, sizeof(*ss->tempVerts)*oldLen);
993
ss->tempEdges = CCGSUBSURF_realloc(ss, ss->tempEdges, sizeof(*ss->tempEdges)*ss->lenTempArrays, sizeof(*ss->tempEdges)*oldLen);
996
if (ss->syncState==eSyncState_Partial) {
997
f = _ehash_lookupWithPrev(ss->fMap, fHDL, &prevp);
999
for (k=0; k<numVerts; k++) {
1000
ss->tempVerts[k] = _ehash_lookup(ss->vMap, vHDLs[k]);
1002
for (k=0; k<numVerts; k++) {
1003
ss->tempEdges[k] = _vert_findEdgeTo(ss->tempVerts[k], ss->tempVerts[(k+1)%numVerts]);
1007
if ( f->numVerts!=numVerts ||
1008
memcmp(FACE_getVerts(f), ss->tempVerts, sizeof(*ss->tempVerts)*numVerts) ||
1009
memcmp(FACE_getEdges(f), ss->tempEdges, sizeof(*ss->tempEdges)*numVerts))
1010
topologyChanged = 1;
1013
if (!f || topologyChanged) {
1014
fNew = _face_new(fHDL, ss->tempVerts, ss->tempEdges, numVerts, ss->subdivLevels, ss->meshIFC.vertDataSize, ss);
1017
ss->numGrids += numVerts - f->numVerts;
1020
fNew->next = f->next;
1022
_face_unlinkMarkAndFree(f, ss);
1024
ss->numGrids += numVerts;
1025
_ehash_insert(ss->fMap, (EHEntry*) fNew);
1028
for (k=0; k<numVerts; k++)
1029
FACE_getVerts(fNew)[k]->flags |= Vert_eEffected;
1032
if (ss->syncState==eSyncState_Vert || ss->syncState==eSyncState_Edge) {
1033
ss->syncState = eSyncState_Face;
1034
} else if (ss->syncState!=eSyncState_Face) {
1035
return eCCGError_InvalidSyncState;
1038
f = _ehash_lookupWithPrev(ss->oldFMap, fHDL, &prevp);
1040
for (k=0; k<numVerts; k++) {
1041
ss->tempVerts[k] = _ehash_lookup(ss->vMap, vHDLs[k]);
1043
if (!ss->tempVerts[k])
1044
return eCCGError_InvalidValue;
1046
for (k=0; k<numVerts; k++) {
1047
ss->tempEdges[k] = _vert_findEdgeTo(ss->tempVerts[k], ss->tempVerts[(k+1)%numVerts]);
1049
if (!ss->tempEdges[k]) {
1050
if (ss->allowEdgeCreation) {
1051
CCGEdge *e = ss->tempEdges[k] = _edge_new((CCGEdgeHDL) -1, ss->tempVerts[k], ss->tempVerts[(k+1)%numVerts], ss->defaultCreaseValue, ss->subdivLevels, ss->meshIFC.vertDataSize, ss);
1052
_ehash_insert(ss->eMap, (EHEntry*) e);
1053
e->v0->flags |= Vert_eEffected;
1054
e->v1->flags |= Vert_eEffected;
1055
if (ss->meshIFC.edgeUserSize) {
1056
memcpy(ccgSubSurf_getEdgeUserData(ss, e), ss->defaultEdgeUserData, ss->meshIFC.edgeUserSize);
1059
return eCCGError_InvalidValue;
1065
if ( f->numVerts!=numVerts ||
1066
memcmp(FACE_getVerts(f), ss->tempVerts, sizeof(*ss->tempVerts)*numVerts) ||
1067
memcmp(FACE_getEdges(f), ss->tempEdges, sizeof(*ss->tempEdges)*numVerts))
1068
topologyChanged = 1;
1071
if (!f || topologyChanged) {
1072
f = _face_new(fHDL, ss->tempVerts, ss->tempEdges, numVerts, ss->subdivLevels, ss->meshIFC.vertDataSize, ss);
1073
_ehash_insert(ss->fMap, (EHEntry*) f);
1074
ss->numGrids += numVerts;
1076
for (k=0; k<numVerts; k++)
1077
FACE_getVerts(f)[k]->flags |= Vert_eEffected;
1080
_ehash_insert(ss->fMap, (EHEntry*) f);
1082
ss->numGrids += f->numVerts;
1084
for (j=0; j<f->numVerts; j++) {
1085
if (FACE_getVerts(f)[j]->flags&Vert_eChanged) {
1086
for (k=0; k<f->numVerts; k++)
1087
FACE_getVerts(f)[k]->flags |= Vert_eEffected;
1095
return eCCGError_None;
1098
static void ccgSubSurf__sync(CCGSubSurf *ss);
1099
CCGError ccgSubSurf_processSync(CCGSubSurf *ss) {
1100
if (ss->syncState==eSyncState_Partial) {
1101
ss->syncState = eSyncState_None;
1103
ccgSubSurf__sync(ss);
1104
} else if (ss->syncState) {
1105
_ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_unlinkMarkAndFree, ss);
1106
_ehash_free(ss->oldEMap, (EHEntryFreeFP) _edge_unlinkMarkAndFree, ss);
1107
_ehash_free(ss->oldVMap, (EHEntryFreeFP) _vert_free, ss);
1108
CCGSUBSURF_free(ss, ss->tempEdges);
1109
CCGSUBSURF_free(ss, ss->tempVerts);
1111
ss->lenTempArrays = 0;
1113
ss->oldFMap = ss->oldEMap = ss->oldVMap = NULL;
1114
ss->tempVerts = NULL;
1115
ss->tempEdges = NULL;
1117
ss->syncState = eSyncState_None;
1119
ccgSubSurf__sync(ss);
1121
return eCCGError_InvalidSyncState;
1124
return eCCGError_None;
1127
static void ccgSubSurf__sync(CCGSubSurf *ss) {
1128
CCGVert **effectedV;
1129
CCGEdge **effectedE;
1130
CCGFace **effectedF;
1131
int numEffectedV, numEffectedE, numEffectedF;
1132
int subdivLevels = ss->subdivLevels;
1133
int vertDataSize = ss->meshIFC.vertDataSize;
1134
int i,ptrIdx,cornerIdx;
1136
void *q = ss->q, *r = ss->r;
1137
int curLvl, nextLvl;
1140
effectedV = CCGSUBSURF_alloc(ss, sizeof(*effectedV)*ss->vMap->numEntries);
1141
effectedE = CCGSUBSURF_alloc(ss, sizeof(*effectedE)*ss->eMap->numEntries);
1142
effectedF = CCGSUBSURF_alloc(ss, sizeof(*effectedF)*ss->fMap->numEntries);
1143
numEffectedV = numEffectedE = numEffectedF = 0;
1144
for (i=0; i<ss->vMap->curSize; i++) {
1145
CCGVert *v = (CCGVert*) ss->vMap->buckets[i];
1146
for (; v; v = v->next) {
1147
if (v->flags&Vert_eEffected) {
1148
effectedV[numEffectedV++] = v;
1150
for (j=0; j<v->numEdges; j++) {
1151
CCGEdge *e = v->edges[j];
1152
if (!(e->flags&Edge_eEffected)) {
1153
effectedE[numEffectedE++] = e;
1154
e->flags |= Edge_eEffected;
1158
for (j=0; j<v->numFaces; j++) {
1159
CCGFace *f = v->faces[j];
1160
if (!(f->flags&Face_eEffected)) {
1161
effectedF[numEffectedF++] = f;
1162
f->flags |= Face_eEffected;
1169
#define VERT_getCo(v, lvl) _vert_getCo(v, lvl, vertDataSize)
1170
#define EDGE_getCo(e, lvl, x) _edge_getCo(e, lvl, x, vertDataSize)
1171
#define FACE_getIECo(f, lvl, S, x) _face_getIECo(f, lvl, S, x, subdivLevels, vertDataSize)
1172
#define FACE_getIFCo(f, lvl, S, x, y) _face_getIFCo(f, lvl, S, x, y, subdivLevels, vertDataSize)
1176
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
1177
CCGFace *f = effectedF[ptrIdx];
1178
void *co = FACE_getCenterData(f);
1180
for (i=0; i<f->numVerts; i++) {
1181
VertDataAdd(co, VERT_getCo(FACE_getVerts(f)[i], curLvl));
1183
VertDataMulN(co, 1.0f/f->numVerts);
1187
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
1188
CCGEdge *e = effectedE[ptrIdx];
1189
void *co = EDGE_getCo(e, nextLvl, 1);
1190
float sharpness = EDGE_getSharpness(e, curLvl, ss);
1192
if (_edge_isBoundary(e) || sharpness>=1.0) {
1193
VertDataCopy(co, VERT_getCo(e->v0, curLvl));
1194
VertDataAdd(co, VERT_getCo(e->v1, curLvl));
1195
VertDataMulN(co, 0.5f);
1198
VertDataCopy(q, VERT_getCo(e->v0, curLvl));
1199
VertDataAdd(q, VERT_getCo(e->v1, curLvl));
1200
for (i=0; i<e->numFaces; i++) {
1201
CCGFace *f = e->faces[i];
1202
VertDataAdd(q, FACE_getCenterData(f));
1205
VertDataMulN(q, 1.0f/(2.0f+numFaces));
1207
VertDataCopy(r, VERT_getCo(e->v0, curLvl));
1208
VertDataAdd(r, VERT_getCo(e->v1, curLvl));
1209
VertDataMulN(r, 0.5f);
1211
VertDataCopy(co, q);
1213
VertDataMulN(r, sharpness);
1217
// edge flags cleared later
1219
for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) {
1220
CCGVert *v = effectedV[ptrIdx];
1221
void *co = VERT_getCo(v, curLvl);
1222
void *nCo = VERT_getCo(v, nextLvl);
1223
int sharpCount = 0, allSharp = 1;
1224
float avgSharpness = 0.0;
1226
for (i=0; i<v->numEdges; i++) {
1227
CCGEdge *e = v->edges[i];
1228
float sharpness = EDGE_getSharpness(e, curLvl, ss);
1230
if (sharpness!=0.0f) {
1232
avgSharpness += sharpness;
1238
avgSharpness /= sharpCount;
1239
if (avgSharpness>1.0) {
1244
VertDataCopy(nCo, co);
1245
} else if (_vert_isBoundary(v)) {
1246
int numBoundary = 0;
1249
for (i=0; i<v->numEdges; i++) {
1250
CCGEdge *e = v->edges[i];
1251
if (_edge_isBoundary(e)) {
1252
VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl));
1256
VertDataCopy(nCo, co);
1257
VertDataMulN(nCo, 0.75);
1258
VertDataMulN(r, 0.25f/numBoundary);
1259
VertDataAdd(nCo, r);
1261
int numEdges = 0, numFaces = 0;
1264
for (i=0; i<v->numFaces; i++) {
1265
CCGFace *f = v->faces[i];
1266
VertDataAdd(q, FACE_getCenterData(f));
1269
VertDataMulN(q, 1.0f/numFaces);
1271
for (i=0; i<v->numEdges; i++) {
1272
CCGEdge *e = v->edges[i];
1273
VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl));
1276
VertDataMulN(r, 1.0f/numEdges);
1278
VertDataCopy(nCo, co);
1279
VertDataMulN(nCo, numEdges-2.0f);
1280
VertDataAdd(nCo, q);
1281
VertDataAdd(nCo, r);
1282
VertDataMulN(nCo, 1.0f/numEdges);
1285
if (sharpCount>1 && v->numFaces) {
1288
for (i=0; i<v->numEdges; i++) {
1289
CCGEdge *e = v->edges[i];
1290
float sharpness = EDGE_getSharpness(e, curLvl, ss);
1292
if (sharpness != 0.0) {
1293
CCGVert *oV = _edge_getOtherVert(e, v);
1294
VertDataAdd(q, VERT_getCo(oV, curLvl));
1298
VertDataMulN(q, (float) 1/sharpCount);
1300
if (sharpCount!=2 || allSharp) {
1301
// q = q + (co-q)*avgSharpness
1302
VertDataCopy(r, co);
1304
VertDataMulN(r, avgSharpness);
1308
// r = co*.75 + q*.25
1309
VertDataCopy(r, co);
1310
VertDataMulN(r, .75);
1311
VertDataMulN(q, .25);
1314
// nCo = nCo + (r-nCo)*avgSharpness
1315
VertDataSub(r, nCo);
1316
VertDataMulN(r, avgSharpness);
1317
VertDataAdd(nCo, r);
1320
// vert flags cleared later
1323
if (ss->useAgeCounts) {
1324
for (i=0; i<numEffectedV; i++) {
1325
CCGVert *v = effectedV[i];
1326
byte *userData = ccgSubSurf_getVertUserData(ss, v);
1327
*((int*) &userData[ss->vertUserAgeOffset]) = ss->currentAge;
1330
for (i=0; i<numEffectedE; i++) {
1331
CCGEdge *e = effectedE[i];
1332
byte *userData = ccgSubSurf_getEdgeUserData(ss, e);
1333
*((int*) &userData[ss->edgeUserAgeOffset]) = ss->currentAge;
1336
for (i=0; i<numEffectedF; i++) {
1337
CCGFace *f = effectedF[i];
1338
byte *userData = ccgSubSurf_getFaceUserData(ss, f);
1339
*((int*) &userData[ss->faceUserAgeOffset]) = ss->currentAge;
1343
for (i=0; i<numEffectedE; i++) {
1344
CCGEdge *e = effectedE[i];
1345
VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl));
1346
VertDataCopy(EDGE_getCo(e, nextLvl, 2), VERT_getCo(e->v1, nextLvl));
1348
for (i=0; i<numEffectedF; i++) {
1349
CCGFace *f = effectedF[i];
1350
for (S=0; S<f->numVerts; S++) {
1351
CCGEdge *e = FACE_getEdges(f)[S];
1352
CCGEdge *prevE = FACE_getEdges(f)[(S+f->numVerts-1)%f->numVerts];
1354
VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), FACE_getCenterData(f));
1355
VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), FACE_getCenterData(f));
1356
VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 1), VERT_getCo(FACE_getVerts(f)[S], nextLvl));
1357
VertDataCopy(FACE_getIECo(f, nextLvl, S, 1), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, 1));
1359
VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 0), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize));
1360
VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 1), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize));
1364
for (curLvl=1; curLvl<subdivLevels; curLvl++) {
1365
int edgeSize = 1 + (1<<curLvl);
1366
int gridSize = 1 + (1<<(curLvl-1));
1369
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
1370
CCGFace *f = (CCGFace*) effectedF[ptrIdx];
1372
/* interior face midpoints
1373
* o old interior face points
1375
for (S=0; S<f->numVerts; S++) {
1376
for (y=0; y<gridSize-1; y++) {
1377
for (x=0; x<gridSize-1; x++) {
1380
void *co0 = FACE_getIFCo(f, curLvl, S, x+0, y+0);
1381
void *co1 = FACE_getIFCo(f, curLvl, S, x+1, y+0);
1382
void *co2 = FACE_getIFCo(f, curLvl, S, x+1, y+1);
1383
void *co3 = FACE_getIFCo(f, curLvl, S, x+0, y+1);
1384
void *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
1386
VertDataAvg4(co, co0, co1, co2, co3);
1391
/* interior edge midpoints
1392
* o old interior edge points
1393
* o new interior face midpoints
1395
for (S=0; S<f->numVerts; S++) {
1396
for (x=0; x<gridSize-1; x++) {
1398
void *co0 = FACE_getIECo(f, curLvl, S, x+0);
1399
void *co1 = FACE_getIECo(f, curLvl, S, x+1);
1400
void *co2 = FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx);
1401
void *co3 = FACE_getIFCo(f, nextLvl, S, fx, 1);
1402
void *co = FACE_getIECo(f, nextLvl, S, fx);
1404
VertDataAvg4(co, co0, co1, co2, co3);
1407
/* interior face interior edge midpoints
1408
* o old interior face points
1409
* o new interior face midpoints
1413
for (x=1; x<gridSize-1; x++) {
1414
for (y=0; y<gridSize-1; y++) {
1417
void *co0 = FACE_getIFCo(f, curLvl, S, x, y+0);
1418
void *co1 = FACE_getIFCo(f, curLvl, S, x, y+1);
1419
void *co2 = FACE_getIFCo(f, nextLvl, S, fx-1, fy);
1420
void *co3 = FACE_getIFCo(f, nextLvl, S, fx+1, fy);
1421
void *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
1423
VertDataAvg4(co, co0, co1, co2, co3);
1428
for (y=1; y<gridSize-1; y++) {
1429
for (x=0; x<gridSize-1; x++) {
1432
void *co0 = FACE_getIFCo(f, curLvl, S, x+0, y);
1433
void *co1 = FACE_getIFCo(f, curLvl, S, x+1, y);
1434
void *co2 = FACE_getIFCo(f, nextLvl, S, fx, fy-1);
1435
void *co3 = FACE_getIFCo(f, nextLvl, S, fx, fy+1);
1436
void *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
1438
VertDataAvg4(co, co0, co1, co2, co3);
1444
/* exterior edge midpoints
1445
* o old exterior edge points
1446
* o new interior face midpoints
1448
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
1449
CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
1450
float sharpness = EDGE_getSharpness(e, curLvl, ss);
1452
if (_edge_isBoundary(e) || sharpness>1.0) {
1453
for (x=0; x<edgeSize-1; x++) {
1455
void *co0 = EDGE_getCo(e, curLvl, x+0);
1456
void *co1 = EDGE_getCo(e, curLvl, x+1);
1457
void *co = EDGE_getCo(e, nextLvl, fx);
1459
VertDataCopy(co, co0);
1460
VertDataAdd(co, co1);
1461
VertDataMulN(co, 0.5);
1464
for (x=0; x<edgeSize-1; x++) {
1466
void *co0 = EDGE_getCo(e, curLvl, x+0);
1467
void *co1 = EDGE_getCo(e, curLvl, x+1);
1468
void *co = EDGE_getCo(e, nextLvl, fx);
1471
VertDataCopy(q, co0);
1472
VertDataAdd(q, co1);
1474
for (i=0; i<e->numFaces; i++) {
1475
CCGFace *f = e->faces[i];
1476
VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx, 1, subdivLevels, vertDataSize));
1480
VertDataMulN(q, 1.0f/(2.0f+numFaces));
1482
VertDataCopy(r, co0);
1483
VertDataAdd(r, co1);
1484
VertDataMulN(r, 0.5);
1486
VertDataCopy(co, q);
1488
VertDataMulN(r, sharpness);
1494
/* exterior vertex shift
1495
* o old vertex points (shifting)
1496
* o old exterior edge points
1497
* o new interior face midpoints
1499
for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) {
1500
CCGVert *v = (CCGVert*) effectedV[ptrIdx];
1501
void *co = VERT_getCo(v, curLvl);
1502
void *nCo = VERT_getCo(v, nextLvl);
1503
int sharpCount = 0, allSharp = 1;
1504
float avgSharpness = 0.0;
1506
for (i=0; i<v->numEdges; i++) {
1507
CCGEdge *e = v->edges[i];
1508
float sharpness = EDGE_getSharpness(e, curLvl, ss);
1510
if (sharpness!=0.0f) {
1512
avgSharpness += sharpness;
1518
avgSharpness /= sharpCount;
1519
if (avgSharpness>1.0) {
1524
VertDataCopy(nCo, co);
1525
} else if (_vert_isBoundary(v)) {
1526
int numBoundary = 0;
1529
for (i=0; i<v->numEdges; i++) {
1530
CCGEdge *e = v->edges[i];
1531
if (_edge_isBoundary(e)) {
1532
VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize));
1537
VertDataCopy(nCo, co);
1538
VertDataMulN(nCo, 0.75);
1539
VertDataMulN(r, 0.25f/numBoundary);
1540
VertDataAdd(nCo, r);
1542
int cornerIdx = (1 + (1<<(curLvl))) - 2;
1543
int numEdges = 0, numFaces = 0;
1546
for (i=0; i<v->numFaces; i++) {
1547
CCGFace *f = v->faces[i];
1548
VertDataAdd(q, FACE_getIFCo(f, nextLvl, _face_getVertIndex(f,v), cornerIdx, cornerIdx));
1551
VertDataMulN(q, 1.0f/numFaces);
1553
for (i=0; i<v->numEdges; i++) {
1554
CCGEdge *e = v->edges[i];
1555
VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1,vertDataSize));
1558
VertDataMulN(r, 1.0f/numEdges);
1560
VertDataCopy(nCo, co);
1561
VertDataMulN(nCo, numEdges-2.0f);
1562
VertDataAdd(nCo, q);
1563
VertDataAdd(nCo, r);
1564
VertDataMulN(nCo, 1.0f/numEdges);
1567
if (sharpCount>1 && v->numFaces) {
1570
for (i=0; i<v->numEdges; i++) {
1571
CCGEdge *e = v->edges[i];
1572
float sharpness = EDGE_getSharpness(e, curLvl, ss);
1574
if (sharpness != 0.0) {
1575
VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize));
1579
VertDataMulN(q, (float) 1/sharpCount);
1581
if (sharpCount!=2 || allSharp) {
1582
// q = q + (co-q)*avgSharpness
1583
VertDataCopy(r, co);
1585
VertDataMulN(r, avgSharpness);
1589
// r = co*.75 + q*.25
1590
VertDataCopy(r, co);
1591
VertDataMulN(r, .75);
1592
VertDataMulN(q, .25);
1595
// nCo = nCo + (r-nCo)*avgSharpness
1596
VertDataSub(r, nCo);
1597
VertDataMulN(r, avgSharpness);
1598
VertDataAdd(nCo, r);
1602
/* exterior edge interior shift
1603
* o old exterior edge midpoints (shifting)
1604
* o old exterior edge midpoints
1605
* o new interior face midpoints
1607
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
1608
CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
1609
float sharpness = EDGE_getSharpness(e, curLvl, ss);
1611
float avgSharpness = 0.0;
1613
if (sharpness!=0.0f) {
1615
avgSharpness += sharpness;
1617
if (avgSharpness>1.0) {
1625
if (_edge_isBoundary(e) && (!e->numFaces || sharpCount<2)) {
1626
for (x=1; x<edgeSize-1; x++) {
1628
void *co = EDGE_getCo(e, curLvl, x);
1629
void *nCo = EDGE_getCo(e, nextLvl, fx);
1630
VertDataCopy(r, EDGE_getCo(e, curLvl, x-1));
1631
VertDataAdd(r, EDGE_getCo(e, curLvl, x+1));
1632
VertDataMulN(r, 0.5);
1633
VertDataCopy(nCo, co);
1634
VertDataMulN(nCo, 0.75);
1635
VertDataMulN(r, 0.25);
1636
VertDataAdd(nCo, r);
1639
for (x=1; x<edgeSize-1; x++) {
1641
void *co = EDGE_getCo(e, curLvl, x);
1642
void *nCo = EDGE_getCo(e, nextLvl, fx);
1647
VertDataAdd(r, EDGE_getCo(e, curLvl, x-1));
1648
VertDataAdd(r, EDGE_getCo(e, curLvl, x+1));
1649
for (i=0; i<e->numFaces; i++) {
1650
CCGFace *f = e->faces[i];
1651
VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx-1, 1, subdivLevels, vertDataSize));
1652
VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx+1, 1, subdivLevels, vertDataSize));
1654
VertDataAdd(r, _face_getIFCoEdge(f, e, curLvl, x, 1, subdivLevels, vertDataSize));
1657
VertDataMulN(q, 1.0/(numFaces*2.0f));
1658
VertDataMulN(r, 1.0/(2.0f + numFaces));
1660
VertDataCopy(nCo, co);
1661
VertDataMulN(nCo, (float) numFaces);
1662
VertDataAdd(nCo, q);
1663
VertDataAdd(nCo, r);
1664
VertDataMulN(nCo, 1.0f/(2+numFaces));
1666
if (sharpCount==2) {
1667
VertDataCopy(q, co);
1668
VertDataMulN(q, 6.0f);
1669
VertDataAdd(q, EDGE_getCo(e, curLvl, x-1));
1670
VertDataAdd(q, EDGE_getCo(e, curLvl, x+1));
1671
VertDataMulN(q, 1/8.0f);
1673
VertDataSub(q, nCo);
1674
VertDataMulN(q, avgSharpness);
1675
VertDataAdd(nCo, q);
1681
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
1682
CCGFace *f = (CCGFace*) effectedF[ptrIdx];
1684
/* interior center point shift
1685
* o old face center point (shifting)
1686
* o old interior edge points
1687
* o new interior face midpoints
1690
for (S=0; S<f->numVerts; S++) {
1691
VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1));
1693
VertDataMulN(q, 1.0f/f->numVerts);
1695
for (S=0; S<f->numVerts; S++) {
1696
VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1));
1698
VertDataMulN(r, 1.0f/f->numVerts);
1700
VertDataMulN(FACE_getCenterData(f), f->numVerts-2.0f);
1701
VertDataAdd(FACE_getCenterData(f), q);
1702
VertDataAdd(FACE_getCenterData(f), r);
1703
VertDataMulN(FACE_getCenterData(f), 1.0f/f->numVerts);
1705
for (S=0; S<f->numVerts; S++) {
1706
/* interior face shift
1707
* o old interior face point (shifting)
1708
* o new interior edge midpoints
1709
* o new interior face midpoints
1711
for (x=1; x<gridSize-1; x++) {
1712
for (y=1; y<gridSize-1; y++) {
1715
void *co = FACE_getIFCo(f, curLvl, S, x, y);
1716
void *nCo = FACE_getIFCo(f, nextLvl, S, fx, fy);
1718
VertDataAvg4(q, FACE_getIFCo(f, nextLvl, S, fx-1, fy-1),
1719
FACE_getIFCo(f, nextLvl, S, fx+1, fy-1),
1720
FACE_getIFCo(f, nextLvl, S, fx+1, fy+1),
1721
FACE_getIFCo(f, nextLvl, S, fx-1, fy+1));
1723
VertDataAvg4(r, FACE_getIFCo(f, nextLvl, S, fx-1, fy+0),
1724
FACE_getIFCo(f, nextLvl, S, fx+1, fy+0),
1725
FACE_getIFCo(f, nextLvl, S, fx+0, fy-1),
1726
FACE_getIFCo(f, nextLvl, S, fx+0, fy+1));
1728
VertDataCopy(nCo, co);
1729
VertDataSub(nCo, q);
1730
VertDataMulN(nCo, 0.25f);
1731
VertDataAdd(nCo, r);
1735
/* interior edge interior shift
1736
* o old interior edge point (shifting)
1737
* o new interior edge midpoints
1738
* o new interior face midpoints
1740
for (x=1; x<gridSize-1; x++) {
1742
void *co = FACE_getIECo(f, curLvl, S, x);
1743
void *nCo = FACE_getIECo(f, nextLvl, S, fx);
1745
VertDataAvg4(q, FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx-1),
1746
FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx+1),
1747
FACE_getIFCo(f, nextLvl, S, fx+1, +1),
1748
FACE_getIFCo(f, nextLvl, S, fx-1, +1));
1750
VertDataAvg4(r, FACE_getIECo(f, nextLvl, S, fx-1),
1751
FACE_getIECo(f, nextLvl, S, fx+1),
1752
FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx),
1753
FACE_getIFCo(f, nextLvl, S, fx, 1));
1755
VertDataCopy(nCo, co);
1756
VertDataSub(nCo, q);
1757
VertDataMulN(nCo, 0.25f);
1758
VertDataAdd(nCo, r);
1764
edgeSize = 1 + (1<<(nextLvl));
1765
gridSize = 1 + (1<<((nextLvl)-1));
1766
cornerIdx = gridSize-1;
1767
for (i=0; i<numEffectedE; i++) {
1768
CCGEdge *e = effectedE[i];
1769
VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl));
1770
VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize-1), VERT_getCo(e->v1, nextLvl));
1772
for (i=0; i<numEffectedF; i++) {
1773
CCGFace *f = effectedF[i];
1774
for (S=0; S<f->numVerts; S++) {
1775
CCGEdge *e = FACE_getEdges(f)[S];
1776
CCGEdge *prevE = FACE_getEdges(f)[(S+f->numVerts-1)%f->numVerts];
1778
VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), FACE_getCenterData(f));
1779
VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), FACE_getCenterData(f));
1780
VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], nextLvl));
1781
VertDataCopy(FACE_getIECo(f, nextLvl, S, cornerIdx), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, cornerIdx));
1782
for (x=1; x<gridSize-1; x++) {
1783
void *co = FACE_getIECo(f, nextLvl, S, x);
1784
VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, 0), co);
1785
VertDataCopy(FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 0, x), co);
1787
for (x=0; x<gridSize-1; x++) {
1788
int eI = gridSize-1-x;
1789
VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, eI,vertDataSize));
1790
VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, eI,vertDataSize));
1796
#define FACE_getIFNo(f, lvl, S, x, y) _face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset)
1797
#define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize)
1798
if (ss->calcVertNormals) {
1799
int lvl = ss->subdivLevels;
1800
int edgeSize = 1 + (1<<lvl);
1801
int gridSize = 1 + (1<<(lvl-1));
1802
int normalDataOffset = ss->normalDataOffset;
1804
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
1805
CCGFace *f = (CCGFace*) effectedF[ptrIdx];
1808
for (S=0; S<f->numVerts; S++) {
1809
for (y=0; y<gridSize-1; y++)
1810
for (x=0; x<gridSize-1; x++)
1811
NormZero(FACE_getIFNo(f, lvl, S, x, y));
1813
if (FACE_getEdges(f)[(S-1+f->numVerts)%f->numVerts]->flags&Edge_eEffected)
1814
for (x=0; x<gridSize-1; x++)
1815
NormZero(FACE_getIFNo(f, lvl, S, x, gridSize-1));
1816
if (FACE_getEdges(f)[S]->flags&Edge_eEffected)
1817
for (y=0; y<gridSize-1; y++)
1818
NormZero(FACE_getIFNo(f, lvl, S, gridSize-1, y));
1819
if (FACE_getVerts(f)[S]->flags&Vert_eEffected)
1820
NormZero(FACE_getIFNo(f, lvl, S, gridSize-1, gridSize-1));
1824
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
1825
CCGFace *f = (CCGFace*) effectedF[ptrIdx];
1829
for (S=0; S<f->numVerts; S++) {
1830
int yLimit = !(FACE_getEdges(f)[(S-1+f->numVerts)%f->numVerts]->flags&Edge_eEffected);
1831
int xLimit = !(FACE_getEdges(f)[S]->flags&Edge_eEffected);
1832
int yLimitNext = xLimit;
1833
int xLimitPrev = yLimit;
1835
for (y=0; y<gridSize - 1; y++) {
1836
for (x=0; x<gridSize - 1; x++) {
1837
int xPlusOk = (!xLimit || x<gridSize-2);
1838
int yPlusOk = (!yLimit || y<gridSize-2);
1840
FACE_calcIFNo(f, lvl, S, x, y, no);
1842
NormAdd(FACE_getIFNo(f, lvl, S, x+0, y+0), no);
1844
NormAdd(FACE_getIFNo(f, lvl, S, x+1, y+0), no);
1846
NormAdd(FACE_getIFNo(f, lvl, S, x+0, y+1), no);
1847
if (xPlusOk && yPlusOk) {
1848
if (x<gridSize-2 || y<gridSize-2 || FACE_getVerts(f)[S]->flags&Vert_eEffected) {
1849
NormAdd(FACE_getIFNo(f, lvl, S, x+1, y+1), no);
1856
if (!yLimitNext || 1<gridSize-1)
1857
NormAdd(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, 1), no);
1858
if (!xLimitPrev || 1<gridSize-1)
1859
NormAdd(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, 1, 0), no);
1861
for (K=0; K<f->numVerts; K++) {
1863
NormAdd(FACE_getIFNo(f, lvl, K, 0, 0), no);
1867
NormAdd(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, x), no);
1868
if (!yLimitNext || x<gridSize-2)
1869
NormAdd(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, x+1), no);
1871
NormAdd(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, y, 0), no);
1872
if (!xLimitPrev || y<gridSize-2)
1873
NormAdd(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, y+1, 0), no);
1879
// XXX can I reduce the number of normalisations here?
1880
for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) {
1881
CCGVert *v = (CCGVert*) effectedV[ptrIdx];
1882
float length, *no = _vert_getNo(v, lvl, vertDataSize, normalDataOffset);
1886
for (i=0; i<v->numFaces; i++) {
1887
CCGFace *f = v->faces[i];
1888
NormAdd(no, FACE_getIFNo(f, lvl, _face_getVertIndex(f,v), gridSize-1, gridSize-1));
1891
length = sqrt(no[0]*no[0] + no[1]*no[1] + no[2]*no[2]);
1893
if (length>FLT_EPSILON) {
1894
float invLength = 1.0f/length;
1902
for (i=0; i<v->numFaces; i++) {
1903
CCGFace *f = v->faces[i];
1904
NormCopy(FACE_getIFNo(f, lvl, _face_getVertIndex(f,v), gridSize-1, gridSize-1), no);
1907
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
1908
CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
1911
CCGFace *fLast = e->faces[e->numFaces-1];
1914
for (i=0; i<e->numFaces-1; i++) {
1915
CCGFace *f = e->faces[i];
1917
for (x=1; x<edgeSize-1; x++) {
1918
NormAdd(_face_getIFNoEdge(fLast, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset),
1919
_face_getIFNoEdge(f, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
1923
for (i=0; i<e->numFaces-1; i++) {
1924
CCGFace *f = e->faces[i];
1926
for (x=1; x<edgeSize-1; x++) {
1927
NormCopy(_face_getIFNoEdge(f, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset),
1928
_face_getIFNoEdge(fLast, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
1933
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
1934
CCGFace *f = (CCGFace*) effectedF[ptrIdx];
1937
for (S=0; S<f->numVerts; S++) {
1938
NormCopy(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, gridSize-1),
1939
FACE_getIFNo(f, lvl, S, gridSize-1, 0));
1942
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
1943
CCGFace *f = (CCGFace*) effectedF[ptrIdx];
1946
for (S=0; S<f->numVerts; S++) {
1947
for (y=0; y<gridSize; y++) {
1948
for (x=0; x<gridSize; x++) {
1949
float *no = FACE_getIFNo(f, lvl, S, x, y);
1950
float length = sqrt(no[0]*no[0] + no[1]*no[1] + no[2]*no[2]);
1952
if (length>FLT_EPSILON) {
1953
float invLength = 1.0f/length;
1967
for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) {
1968
CCGVert *v = effectedV[ptrIdx];
1971
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
1972
CCGEdge *e = effectedE[ptrIdx];
1981
CCGSUBSURF_free(ss, effectedF);
1982
CCGSUBSURF_free(ss, effectedE);
1983
CCGSUBSURF_free(ss, effectedV);
1986
/*** External API accessor functions ***/
1988
int ccgSubSurf_getNumVerts(CCGSubSurf *ss) {
1989
return ss->vMap->numEntries;
1991
int ccgSubSurf_getNumEdges(CCGSubSurf *ss) {
1992
return ss->eMap->numEntries;
1994
int ccgSubSurf_getNumFaces(CCGSubSurf *ss) {
1995
return ss->fMap->numEntries;
1998
CCGVert *ccgSubSurf_getVert(CCGSubSurf *ss, CCGVertHDL v) {
1999
return (CCGVert*) _ehash_lookup(ss->vMap, v);
2001
CCGEdge *ccgSubSurf_getEdge(CCGSubSurf *ss, CCGEdgeHDL e) {
2002
return (CCGEdge*) _ehash_lookup(ss->eMap, e);
2004
CCGFace *ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f) {
2005
return (CCGFace*) _ehash_lookup(ss->fMap, f);
2008
int ccgSubSurf_getSubdivisionLevels(CCGSubSurf *ss) {
2009
return ss->subdivLevels;
2011
int ccgSubSurf_getEdgeSize(CCGSubSurf *ss) {
2012
return ccgSubSurf_getEdgeLevelSize(ss, ss->subdivLevels);
2014
int ccgSubSurf_getEdgeLevelSize(CCGSubSurf *ss, int level) {
2015
if (level<1 || level>ss->subdivLevels) {
2018
return 1 + (1<<level);
2021
int ccgSubSurf_getGridSize(CCGSubSurf *ss) {
2022
return ccgSubSurf_getGridLevelSize(ss, ss->subdivLevels);
2024
int ccgSubSurf_getGridLevelSize(CCGSubSurf *ss, int level) {
2025
if (level<1 || level>ss->subdivLevels) {
2028
return 1 + (1<<(level-1));
2032
/* Vert accessors */
2034
CCGVertHDL ccgSubSurf_getVertVertHandle(CCGSubSurf *ss, CCGVert *v) {
2037
int ccgSubSurf_getVertAge(CCGSubSurf *ss, CCGVert *v) {
2038
if (ss->useAgeCounts) {
2039
byte *userData = ccgSubSurf_getVertUserData(ss, v);
2040
return ss->currentAge - *((int*) &userData[ss->vertUserAgeOffset]);
2045
void *ccgSubSurf_getVertUserData(CCGSubSurf *ss, CCGVert *v) {
2046
return VERT_getLevelData(v) + ss->meshIFC.vertDataSize*(ss->subdivLevels+1);
2048
int ccgSubSurf_getVertNumFaces(CCGSubSurf *ss, CCGVert *v) {
2051
CCGFace *ccgSubSurf_getVertFace(CCGSubSurf *ss, CCGVert *v, int index) {
2052
if (index<0 || index>=v->numFaces) {
2055
return v->faces[index];
2058
int ccgSubSurf_getVertNumEdges(CCGSubSurf *ss, CCGVert *v) {
2061
CCGEdge *ccgSubSurf_getVertEdge(CCGSubSurf *ss, CCGVert *v, int index) {
2062
if (index<0 || index>=v->numEdges) {
2065
return v->edges[index];
2068
void *ccgSubSurf_getVertData(CCGSubSurf *ss, CCGVert *v) {
2069
return ccgSubSurf_getVertLevelData(ss, v, ss->subdivLevels);
2071
void *ccgSubSurf_getVertLevelData(CCGSubSurf *ss, CCGVert *v, int level) {
2072
if (level<0 || level>ss->subdivLevels) {
2075
return _vert_getCo(v, level, ss->meshIFC.vertDataSize);
2079
/* Edge accessors */
2081
CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle(CCGSubSurf *ss, CCGEdge *e) {
2084
int ccgSubSurf_getEdgeAge(CCGSubSurf *ss, CCGEdge *e) {
2085
if (ss->useAgeCounts) {
2086
byte *userData = ccgSubSurf_getEdgeUserData(ss, e);
2087
return ss->currentAge - *((int*) &userData[ss->edgeUserAgeOffset]);
2092
void *ccgSubSurf_getEdgeUserData(CCGSubSurf *ss, CCGEdge *e) {
2093
return EDGE_getLevelData(e) + ss->meshIFC.vertDataSize *((ss->subdivLevels+1) + (1<<(ss->subdivLevels+1))-1);
2095
int ccgSubSurf_getEdgeNumFaces(CCGSubSurf *ss, CCGEdge *e) {
2098
CCGFace *ccgSubSurf_getEdgeFace(CCGSubSurf *ss, CCGEdge *e, int index) {
2099
if (index<0 || index>=e->numFaces) {
2102
return e->faces[index];
2105
CCGVert *ccgSubSurf_getEdgeVert0(CCGSubSurf *ss, CCGEdge *e) {
2108
CCGVert *ccgSubSurf_getEdgeVert1(CCGSubSurf *ss, CCGEdge *e) {
2111
void *ccgSubSurf_getEdgeDataArray(CCGSubSurf *ss, CCGEdge *e) {
2112
return ccgSubSurf_getEdgeData(ss, e, 0);
2114
void *ccgSubSurf_getEdgeData(CCGSubSurf *ss, CCGEdge *e, int x) {
2115
return ccgSubSurf_getEdgeLevelData(ss, e, x, ss->subdivLevels);
2117
void *ccgSubSurf_getEdgeLevelData(CCGSubSurf *ss, CCGEdge *e, int x, int level) {
2118
if (level<0 || level>ss->subdivLevels) {
2121
return _edge_getCo(e, level, x, ss->meshIFC.vertDataSize);
2125
/* Face accessors */
2127
CCGFaceHDL ccgSubSurf_getFaceFaceHandle(CCGSubSurf *ss, CCGFace *f) {
2130
int ccgSubSurf_getFaceAge(CCGSubSurf *ss, CCGFace *f) {
2131
if (ss->useAgeCounts) {
2132
byte *userData = ccgSubSurf_getFaceUserData(ss, f);
2133
return ss->currentAge - *((int*) &userData[ss->faceUserAgeOffset]);
2138
void *ccgSubSurf_getFaceUserData(CCGSubSurf *ss, CCGFace *f) {
2139
int maxGridSize = 1 + (1<<(ss->subdivLevels-1));
2140
return FACE_getCenterData(f) + ss->meshIFC.vertDataSize *(1 + f->numVerts*maxGridSize + f->numVerts*maxGridSize*maxGridSize);
2142
int ccgSubSurf_getFaceNumVerts(CCGSubSurf *ss, CCGFace *f) {
2145
CCGVert *ccgSubSurf_getFaceVert(CCGSubSurf *ss, CCGFace *f, int index) {
2146
if (index<0 || index>=f->numVerts) {
2149
return FACE_getVerts(f)[index];
2152
CCGEdge *ccgSubSurf_getFaceEdge(CCGSubSurf *ss, CCGFace *f, int index) {
2153
if (index<0 || index>=f->numVerts) {
2156
return FACE_getEdges(f)[index];
2159
int ccgSubSurf_getFaceEdgeIndex(CCGSubSurf *ss, CCGFace *f, CCGEdge *e) {
2162
for (i=0; i<f->numVerts; i++)
2163
if (FACE_getEdges(f)[i]==e)
2168
void *ccgSubSurf_getFaceCenterData(CCGSubSurf *ss, CCGFace *f) {
2169
return FACE_getCenterData(f);
2171
void *ccgSubSurf_getFaceGridEdgeDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex) {
2172
return ccgSubSurf_getFaceGridEdgeData(ss, f, gridIndex, 0);
2174
void *ccgSubSurf_getFaceGridEdgeData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x) {
2175
return _face_getIECo(f, ss->subdivLevels, gridIndex, x, ss->subdivLevels, ss->meshIFC.vertDataSize);
2177
void *ccgSubSurf_getFaceGridDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex) {
2178
return ccgSubSurf_getFaceGridData(ss, f, gridIndex, 0, 0);
2180
void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y) {
2181
return _face_getIFCo(f, ss->subdivLevels, gridIndex, x, y, ss->subdivLevels, ss->meshIFC.vertDataSize);
2184
/*** External API iterator functions ***/
2186
CCGVertIterator *ccgSubSurf_getVertIterator(CCGSubSurf *ss) {
2187
return (CCGVertIterator*) _ehashIterator_new(ss->vMap);
2189
CCGEdgeIterator *ccgSubSurf_getEdgeIterator(CCGSubSurf *ss) {
2190
return (CCGEdgeIterator*) _ehashIterator_new(ss->eMap);
2192
CCGFaceIterator *ccgSubSurf_getFaceIterator(CCGSubSurf *ss) {
2193
return (CCGFaceIterator*) _ehashIterator_new(ss->fMap);
2196
CCGVert *ccgVertIterator_getCurrent(CCGVertIterator *vi) {
2197
return (CCGVert*) _ehashIterator_getCurrent((EHashIterator*) vi);
2199
int ccgVertIterator_isStopped(CCGVertIterator *vi) {
2200
return _ehashIterator_isStopped((EHashIterator*) vi);
2202
void ccgVertIterator_next(CCGVertIterator *vi) {
2203
_ehashIterator_next((EHashIterator*) vi);
2205
void ccgVertIterator_free(CCGVertIterator *vi) {
2206
_ehashIterator_free((EHashIterator*) vi);
2209
CCGEdge *ccgEdgeIterator_getCurrent(CCGEdgeIterator *vi) {
2210
return (CCGEdge*) _ehashIterator_getCurrent((EHashIterator*) vi);
2212
int ccgEdgeIterator_isStopped(CCGEdgeIterator *vi) {
2213
return _ehashIterator_isStopped((EHashIterator*) vi);
2215
void ccgEdgeIterator_next(CCGEdgeIterator *vi) {
2216
_ehashIterator_next((EHashIterator*) vi);
2218
void ccgEdgeIterator_free(CCGEdgeIterator *vi) {
2219
_ehashIterator_free((EHashIterator*) vi);
2222
CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *vi) {
2223
return (CCGFace*) _ehashIterator_getCurrent((EHashIterator*) vi);
2225
int ccgFaceIterator_isStopped(CCGFaceIterator *vi) {
2226
return _ehashIterator_isStopped((EHashIterator*) vi);
2228
void ccgFaceIterator_next(CCGFaceIterator *vi) {
2229
_ehashIterator_next((EHashIterator*) vi);
2231
void ccgFaceIterator_free(CCGFaceIterator *vi) {
2232
_ehashIterator_free((EHashIterator*) vi);
2235
/*** Extern API final vert/edge/face interface ***/
2237
int ccgSubSurf_getNumFinalVerts(CCGSubSurf *ss) {
2238
int edgeSize = 1 + (1<<ss->subdivLevels);
2239
int gridSize = 1 + (1<<(ss->subdivLevels-1));
2240
int numFinalVerts = ss->vMap->numEntries + ss->eMap->numEntries*(edgeSize-2) + ss->fMap->numEntries + ss->numGrids*((gridSize-2) + ((gridSize-2)*(gridSize-2)));
2241
return numFinalVerts;
2243
int ccgSubSurf_getNumFinalEdges(CCGSubSurf *ss) {
2244
int edgeSize = 1 + (1<<ss->subdivLevels);
2245
int gridSize = 1 + (1<<(ss->subdivLevels-1));
2246
int numFinalEdges = ss->eMap->numEntries*(edgeSize-1) + ss->numGrids*((gridSize-1) + 2*((gridSize-2)*(gridSize-1)));
2247
return numFinalEdges;
2249
int ccgSubSurf_getNumFinalFaces(CCGSubSurf *ss) {
2250
int gridSize = 1 + (1<<(ss->subdivLevels-1));
2251
int numFinalFaces = ss->numGrids*((gridSize-1)*(gridSize-1));
2252
return numFinalFaces;