Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / CCGSubSurf.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/blenkernel/intern/CCGSubSurf.c
22  *  \ingroup bke
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <math.h>
28
29 #include "MEM_guardedalloc.h"
30 #include "BLI_sys_types.h" // for intptr_t support
31
32 #include "BLI_utildefines.h" /* for BLI_assert */
33 #include "BLI_math.h"
34
35 #include "BKE_ccg.h"
36 #include "CCGSubSurf.h"
37 #include "CCGSubSurf_intern.h"
38 #include "BKE_subsurf.h"
39
40 #ifdef WITH_OPENSUBDIV
41 #  include "opensubdiv_capi.h"
42 #  include "opensubdiv_converter_capi.h"
43 #  include "opensubdiv_evaluator_capi.h"
44 #  include "opensubdiv_topology_refiner_capi.h"
45 #endif
46
47 #include "GPU_glew.h"
48
49 /***/
50
51 int BKE_ccg_gridsize(int level)
52 {
53         return ccg_gridsize(level);
54 }
55
56 int BKE_ccg_factor(int low_level, int high_level)
57 {
58         BLI_assert(low_level > 0 && high_level > 0);
59         BLI_assert(low_level <= high_level);
60
61         return 1 << (high_level - low_level);
62 }
63
64 /***/
65
66 static CCGVert *_vert_new(CCGVertHDL vHDL, CCGSubSurf *ss)
67 {
68         int num_vert_data = ss->subdivLevels + 1;
69         CCGVert *v = CCGSUBSURF_alloc(ss,
70                                       sizeof(CCGVert) +
71                                       ss->meshIFC.vertDataSize * num_vert_data +
72                                       ss->meshIFC.vertUserSize);
73         byte *userData;
74
75         v->vHDL = vHDL;
76         v->edges = NULL;
77         v->faces = NULL;
78         v->numEdges = v->numFaces = 0;
79         v->flags = 0;
80
81         userData = ccgSubSurf_getVertUserData(ss, v);
82         memset(userData, 0, ss->meshIFC.vertUserSize);
83         if (ss->useAgeCounts) *((int *) &userData[ss->vertUserAgeOffset]) = ss->currentAge;
84
85         return v;
86 }
87 static void _vert_remEdge(CCGVert *v, CCGEdge *e)
88 {
89         int i;
90         for (i = 0; i < v->numEdges; i++) {
91                 if (v->edges[i] == e) {
92                         v->edges[i] = v->edges[--v->numEdges];
93                         break;
94                 }
95         }
96 }
97 static void _vert_remFace(CCGVert *v, CCGFace *f)
98 {
99         int i;
100         for (i = 0; i < v->numFaces; i++) {
101                 if (v->faces[i] == f) {
102                         v->faces[i] = v->faces[--v->numFaces];
103                         break;
104                 }
105         }
106 }
107 static void _vert_addEdge(CCGVert *v, CCGEdge *e, CCGSubSurf *ss)
108 {
109         v->edges = CCGSUBSURF_realloc(ss, v->edges, (v->numEdges + 1) * sizeof(*v->edges), v->numEdges * sizeof(*v->edges));
110         v->edges[v->numEdges++] = e;
111 }
112 static void _vert_addFace(CCGVert *v, CCGFace *f, CCGSubSurf *ss)
113 {
114         v->faces = CCGSUBSURF_realloc(ss, v->faces, (v->numFaces + 1) * sizeof(*v->faces), v->numFaces * sizeof(*v->faces));
115         v->faces[v->numFaces++] = f;
116 }
117 static CCGEdge *_vert_findEdgeTo(const CCGVert *v, const CCGVert *vQ)
118 {
119         int i;
120         for (i = 0; i < v->numEdges; i++) {
121                 CCGEdge *e = v->edges[v->numEdges - 1 - i]; // XXX, note reverse
122                 if ((e->v0 == v && e->v1 == vQ) ||
123                     (e->v1 == v && e->v0 == vQ))
124                 {
125                         return e;
126                 }
127         }
128         return NULL;
129 }
130 static void _vert_free(CCGVert *v, CCGSubSurf *ss)
131 {
132         if (v->edges) {
133                 CCGSUBSURF_free(ss, v->edges);
134         }
135
136         if (v->faces) {
137                 CCGSUBSURF_free(ss, v->faces);
138         }
139
140         CCGSUBSURF_free(ss, v);
141 }
142
143 /***/
144
145 static CCGEdge *_edge_new(CCGEdgeHDL eHDL, CCGVert *v0, CCGVert *v1, float crease, CCGSubSurf *ss)
146 {
147         int num_edge_data = ccg_edgebase(ss->subdivLevels + 1);
148         CCGEdge *e = CCGSUBSURF_alloc(ss,
149                                       sizeof(CCGEdge) +
150                                       ss->meshIFC.vertDataSize * num_edge_data +
151                                       ss->meshIFC.edgeUserSize);
152         byte *userData;
153
154         e->eHDL = eHDL;
155         e->v0 = v0;
156         e->v1 = v1;
157         e->crease = crease;
158         e->faces = NULL;
159         e->numFaces = 0;
160         e->flags = 0;
161         _vert_addEdge(v0, e, ss);
162         _vert_addEdge(v1, e, ss);
163
164         userData = ccgSubSurf_getEdgeUserData(ss, e);
165         memset(userData, 0, ss->meshIFC.edgeUserSize);
166         if (ss->useAgeCounts) *((int *) &userData[ss->edgeUserAgeOffset]) = ss->currentAge;
167
168         return e;
169 }
170 static void _edge_remFace(CCGEdge *e, CCGFace *f)
171 {
172         int i;
173         for (i = 0; i < e->numFaces; i++) {
174                 if (e->faces[i] == f) {
175                         e->faces[i] = e->faces[--e->numFaces];
176                         break;
177                 }
178         }
179 }
180 static void _edge_addFace(CCGEdge *e, CCGFace *f, CCGSubSurf *ss)
181 {
182         e->faces = CCGSUBSURF_realloc(ss, e->faces, (e->numFaces + 1) * sizeof(*e->faces), e->numFaces * sizeof(*e->faces));
183         e->faces[e->numFaces++] = f;
184 }
185 static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSize)
186 {
187         int levelBase = ccg_edgebase(lvl);
188         if (v == e->v0) {
189                 return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
190         }
191         else {
192                 return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
193         }
194 }
195
196 static void _edge_free(CCGEdge *e, CCGSubSurf *ss)
197 {
198         if (e->faces) {
199                 CCGSUBSURF_free(ss, e->faces);
200         }
201
202         CCGSUBSURF_free(ss, e);
203 }
204 static void _edge_unlinkMarkAndFree(CCGEdge *e, CCGSubSurf *ss)
205 {
206         _vert_remEdge(e->v0, e);
207         _vert_remEdge(e->v1, e);
208         e->v0->flags |= Vert_eEffected;
209         e->v1->flags |= Vert_eEffected;
210         _edge_free(e, ss);
211 }
212
213 static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, CCGSubSurf *ss)
214 {
215         int maxGridSize = ccg_gridsize(ss->subdivLevels);
216         int num_face_data = (numVerts * maxGridSize +
217                              numVerts * maxGridSize * maxGridSize + 1);
218         CCGFace *f = CCGSUBSURF_alloc(ss,
219                                       sizeof(CCGFace) +
220                                       sizeof(CCGVert *) * numVerts +
221                                       sizeof(CCGEdge *) * numVerts +
222                                       ss->meshIFC.vertDataSize * num_face_data +
223                                       ss->meshIFC.faceUserSize);
224         byte *userData;
225         int i;
226
227         f->numVerts = numVerts;
228         f->fHDL = fHDL;
229         f->flags = 0;
230
231         for (i = 0; i < numVerts; i++) {
232                 FACE_getVerts(f)[i] = verts[i];
233                 FACE_getEdges(f)[i] = edges[i];
234                 _vert_addFace(verts[i], f, ss);
235                 _edge_addFace(edges[i], f, ss);
236         }
237
238         userData = ccgSubSurf_getFaceUserData(ss, f);
239         memset(userData, 0, ss->meshIFC.faceUserSize);
240         if (ss->useAgeCounts) *((int *) &userData[ss->faceUserAgeOffset]) = ss->currentAge;
241
242         return f;
243 }
244 static void _face_free(CCGFace *f, CCGSubSurf *ss)
245 {
246         CCGSUBSURF_free(ss, f);
247 }
248 static void _face_unlinkMarkAndFree(CCGFace *f, CCGSubSurf *ss)
249 {
250         int j;
251         for (j = 0; j < f->numVerts; j++) {
252                 _vert_remFace(FACE_getVerts(f)[j], f);
253                 _edge_remFace(FACE_getEdges(f)[j], f);
254                 FACE_getVerts(f)[j]->flags |= Vert_eEffected;
255         }
256         _face_free(f, ss);
257 }
258
259 /***/
260
261 CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator)
262 {
263         if (!allocatorIFC) {
264                 allocatorIFC = ccg_getStandardAllocatorIFC();
265                 allocator = NULL;
266         }
267
268         if (subdivLevels < 1) {
269                 return NULL;
270         }
271         else {
272                 CCGSubSurf *ss = allocatorIFC->alloc(allocator, sizeof(*ss));
273
274                 ss->allocatorIFC = *allocatorIFC;
275                 ss->allocator = allocator;
276
277                 ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
278                 ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
279                 ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
280
281                 ss->meshIFC = *ifc;
282
283                 ss->subdivLevels = subdivLevels;
284                 ss->numGrids = 0;
285                 ss->allowEdgeCreation = 0;
286                 ss->defaultCreaseValue = 0;
287                 ss->defaultEdgeUserData = NULL;
288
289                 ss->useAgeCounts = 0;
290                 ss->vertUserAgeOffset = ss->edgeUserAgeOffset = ss->faceUserAgeOffset = 0;
291
292                 ss->calcVertNormals = 0;
293                 ss->normalDataOffset = 0;
294
295                 ss->allocMask = 0;
296
297                 ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
298                 ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
299
300                 ss->currentAge = 0;
301
302                 ss->syncState = eSyncState_None;
303
304                 ss->oldVMap = ss->oldEMap = ss->oldFMap = NULL;
305                 ss->lenTempArrays = 0;
306                 ss->tempVerts = NULL;
307                 ss->tempEdges = NULL;
308
309 #ifdef WITH_OPENSUBDIV
310                 ss->osd_evaluator = NULL;
311                 ss->osd_mesh = NULL;
312                 ss->osd_topology_refiner = NULL;
313                 ss->osd_mesh_invalid = false;
314                 ss->osd_coarse_coords_invalid = false;
315                 ss->osd_vao = 0;
316                 ss->skip_grids = false;
317                 ss->osd_compute = 0;
318                 ss->osd_next_face_ptex_index = 0;
319                 ss->osd_coarse_coords = NULL;
320                 ss->osd_num_coarse_coords = 0;
321                 ss->osd_subdiv_uvs = false;
322 #endif
323
324                 return ss;
325         }
326 }
327
328 void ccgSubSurf_free(CCGSubSurf *ss)
329 {
330         CCGAllocatorIFC allocatorIFC = ss->allocatorIFC;
331         CCGAllocatorHDL allocator = ss->allocator;
332 #ifdef WITH_OPENSUBDIV
333         if (ss->osd_evaluator != NULL) {
334                 openSubdiv_deleteEvaluator(ss->osd_evaluator);
335         }
336         if (ss->osd_mesh != NULL) {
337                 ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
338         }
339         if (ss->osd_vao != 0) {
340                 ccgSubSurf__delete_vertex_array(ss->osd_vao);
341         }
342         if (ss->osd_coarse_coords != NULL) {
343                 MEM_freeN(ss->osd_coarse_coords);
344         }
345         if (ss->osd_topology_refiner != NULL) {
346                 openSubdiv_deleteTopologyRefiner(ss->osd_topology_refiner);
347         }
348 #endif
349
350         if (ss->syncState) {
351                 ccg_ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_free, ss);
352                 ccg_ehash_free(ss->oldEMap, (EHEntryFreeFP) _edge_free, ss);
353                 ccg_ehash_free(ss->oldVMap, (EHEntryFreeFP) _vert_free, ss);
354
355                 MEM_freeN(ss->tempVerts);
356                 MEM_freeN(ss->tempEdges);
357         }
358
359         CCGSUBSURF_free(ss, ss->r);
360         CCGSUBSURF_free(ss, ss->q);
361         if (ss->defaultEdgeUserData) CCGSUBSURF_free(ss, ss->defaultEdgeUserData);
362
363         ccg_ehash_free(ss->fMap, (EHEntryFreeFP) _face_free, ss);
364         ccg_ehash_free(ss->eMap, (EHEntryFreeFP) _edge_free, ss);
365         ccg_ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss);
366
367         CCGSUBSURF_free(ss, ss);
368
369         if (allocatorIFC.release) {
370                 allocatorIFC.release(allocator);
371         }
372 }
373
374 CCGError ccgSubSurf_setAllowEdgeCreation(CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue, void *defaultUserData)
375 {
376         if (ss->defaultEdgeUserData) {
377                 CCGSUBSURF_free(ss, ss->defaultEdgeUserData);
378         }
379
380         ss->allowEdgeCreation = !!allowEdgeCreation;
381         ss->defaultCreaseValue = defaultCreaseValue;
382         ss->defaultEdgeUserData = CCGSUBSURF_alloc(ss, ss->meshIFC.edgeUserSize);
383
384         if (defaultUserData) {
385                 memcpy(ss->defaultEdgeUserData, defaultUserData, ss->meshIFC.edgeUserSize);
386         }
387         else {
388                 memset(ss->defaultEdgeUserData, 0, ss->meshIFC.edgeUserSize);
389         }
390
391         return eCCGError_None;
392 }
393 void ccgSubSurf_getAllowEdgeCreation(CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r, void *defaultUserData_r)
394 {
395         if (allowEdgeCreation_r) *allowEdgeCreation_r = ss->allowEdgeCreation;
396         if (ss->allowEdgeCreation) {
397                 if (defaultCreaseValue_r) *defaultCreaseValue_r = ss->defaultCreaseValue;
398                 if (defaultUserData_r) memcpy(defaultUserData_r, ss->defaultEdgeUserData, ss->meshIFC.edgeUserSize);
399         }
400 }
401
402 CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
403 {
404         if (subdivisionLevels <= 0) {
405                 return eCCGError_InvalidValue;
406         }
407         else if (subdivisionLevels != ss->subdivLevels) {
408                 ss->numGrids = 0;
409                 ss->subdivLevels = subdivisionLevels;
410                 ccg_ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss);
411                 ccg_ehash_free(ss->eMap, (EHEntryFreeFP) _edge_free, ss);
412                 ccg_ehash_free(ss->fMap, (EHEntryFreeFP) _face_free, ss);
413                 ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
414                 ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
415                 ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
416         }
417
418         return eCCGError_None;
419 }
420
421 void ccgSubSurf_getUseAgeCounts(CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r)
422 {
423         *useAgeCounts_r = ss->useAgeCounts;
424
425         if (vertUserOffset_r) *vertUserOffset_r = ss->vertUserAgeOffset;
426         if (edgeUserOffset_r) *edgeUserOffset_r = ss->edgeUserAgeOffset;
427         if (faceUserOffset_r) *faceUserOffset_r = ss->faceUserAgeOffset;
428 }
429
430 CCGError ccgSubSurf_setUseAgeCounts(CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset)
431 {
432         if (useAgeCounts) {
433                 if ((vertUserOffset + 4 > ss->meshIFC.vertUserSize) ||
434                     (edgeUserOffset + 4 > ss->meshIFC.edgeUserSize) ||
435                     (faceUserOffset + 4 > ss->meshIFC.faceUserSize))
436                 {
437                         return eCCGError_InvalidValue;
438                 }
439                 else {
440                         ss->useAgeCounts = 1;
441                         ss->vertUserAgeOffset = vertUserOffset;
442                         ss->edgeUserAgeOffset = edgeUserOffset;
443                         ss->faceUserAgeOffset = faceUserOffset;
444                 }
445         }
446         else {
447                 ss->useAgeCounts = 0;
448                 ss->vertUserAgeOffset = ss->edgeUserAgeOffset = ss->faceUserAgeOffset = 0;
449         }
450
451         return eCCGError_None;
452 }
453
454 CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int normalDataOffset)
455 {
456         if (useVertNormals) {
457                 if (normalDataOffset < 0 || normalDataOffset + 12 > ss->meshIFC.vertDataSize) {
458                         return eCCGError_InvalidValue;
459                 }
460                 else {
461                         ss->calcVertNormals = 1;
462                         ss->normalDataOffset = normalDataOffset;
463                 }
464         }
465         else {
466                 ss->calcVertNormals = 0;
467                 ss->normalDataOffset = 0;
468         }
469
470         return eCCGError_None;
471 }
472
473 void ccgSubSurf_setAllocMask(CCGSubSurf *ss, int allocMask, int maskOffset)
474 {
475         ss->allocMask = allocMask;
476         ss->maskDataOffset = maskOffset;
477 }
478
479 void ccgSubSurf_setNumLayers(CCGSubSurf *ss, int numLayers)
480 {
481         ss->meshIFC.numLayers = numLayers;
482 }
483
484 /***/
485
486 CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss)
487 {
488         if (ss->syncState != eSyncState_None) {
489                 return eCCGError_InvalidSyncState;
490         }
491
492         ss->currentAge++;
493
494         ss->oldVMap = ss->vMap;
495         ss->oldEMap = ss->eMap;
496         ss->oldFMap = ss->fMap;
497
498         ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
499         ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
500         ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
501
502         ss->numGrids = 0;
503
504         ss->lenTempArrays = 12;
505         ss->tempVerts = MEM_mallocN(sizeof(*ss->tempVerts) * ss->lenTempArrays, "CCGSubsurf tempVerts");
506         ss->tempEdges = MEM_mallocN(sizeof(*ss->tempEdges) * ss->lenTempArrays, "CCGSubsurf tempEdges");
507
508         ss->syncState = eSyncState_Vert;
509 #ifdef WITH_OPENSUBDIV
510         ss->osd_next_face_ptex_index = 0;
511 #endif
512
513         return eCCGError_None;
514 }
515
516 CCGError ccgSubSurf_initPartialSync(CCGSubSurf *ss)
517 {
518         if (ss->syncState != eSyncState_None) {
519                 return eCCGError_InvalidSyncState;
520         }
521
522         ss->currentAge++;
523
524         ss->syncState = eSyncState_Partial;
525
526         return eCCGError_None;
527 }
528
529 CCGError ccgSubSurf_syncVertDel(CCGSubSurf *ss, CCGVertHDL vHDL)
530 {
531         if (ss->syncState != eSyncState_Partial) {
532                 return eCCGError_InvalidSyncState;
533         }
534         else {
535                 void **prevp;
536                 CCGVert *v = ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
537
538                 if (!v || v->numFaces || v->numEdges) {
539                         return eCCGError_InvalidValue;
540                 }
541                 else {
542                         *prevp = v->next;
543                         _vert_free(v, ss);
544                 }
545         }
546
547         return eCCGError_None;
548 }
549
550 CCGError ccgSubSurf_syncEdgeDel(CCGSubSurf *ss, CCGEdgeHDL eHDL)
551 {
552         if (ss->syncState != eSyncState_Partial) {
553                 return eCCGError_InvalidSyncState;
554         }
555         else {
556                 void **prevp;
557                 CCGEdge *e = ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp);
558
559                 if (!e || e->numFaces) {
560                         return eCCGError_InvalidValue;
561                 }
562                 else {
563                         *prevp = e->next;
564                         _edge_unlinkMarkAndFree(e, ss);
565                 }
566         }
567
568         return eCCGError_None;
569 }
570
571 CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL)
572 {
573         if (ss->syncState != eSyncState_Partial) {
574                 return eCCGError_InvalidSyncState;
575         }
576         else {
577                 void **prevp;
578                 CCGFace *f = ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp);
579
580                 if (!f) {
581                         return eCCGError_InvalidValue;
582                 }
583                 else {
584                         *prevp = f->next;
585                         _face_unlinkMarkAndFree(f, ss);
586                 }
587         }
588
589         return eCCGError_None;
590 }
591
592 CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r)
593 {
594         void **prevp;
595         CCGVert *v = NULL;
596         short seamflag = (seam) ? Vert_eSeam : 0;
597
598         if (ss->syncState == eSyncState_Partial) {
599                 v = ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
600                 if (!v) {
601                         v = _vert_new(vHDL, ss);
602                         VertDataCopy(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss);
603                         ccg_ehash_insert(ss->vMap, (EHEntry *) v);
604                         v->flags = Vert_eEffected | seamflag;
605                 }
606                 else if (!VertDataEqual(vertData, ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), ss) ||
607                          ((v->flags & Vert_eSeam) != seamflag))
608                 {
609                         int i, j;
610
611                         VertDataCopy(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss);
612                         v->flags = Vert_eEffected | seamflag;
613
614                         for (i = 0; i < v->numEdges; i++) {
615                                 CCGEdge *e = v->edges[i];
616                                 e->v0->flags |= Vert_eEffected;
617                                 e->v1->flags |= Vert_eEffected;
618                         }
619                         for (i = 0; i < v->numFaces; i++) {
620                                 CCGFace *f = v->faces[i];
621                                 for (j = 0; j < f->numVerts; j++) {
622                                         FACE_getVerts(f)[j]->flags |= Vert_eEffected;
623                                 }
624                         }
625                 }
626         }
627         else {
628                 if (ss->syncState != eSyncState_Vert) {
629                         return eCCGError_InvalidSyncState;
630                 }
631
632                 v = ccg_ehash_lookupWithPrev(ss->oldVMap, vHDL, &prevp);
633                 if (!v) {
634                         v = _vert_new(vHDL, ss);
635                         VertDataCopy(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss);
636                         ccg_ehash_insert(ss->vMap, (EHEntry *) v);
637                         v->flags = Vert_eEffected | seamflag;
638                 }
639                 else if (!VertDataEqual(vertData, ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), ss) ||
640                          ((v->flags & Vert_eSeam) != seamflag))
641                 {
642                         *prevp = v->next;
643                         ccg_ehash_insert(ss->vMap, (EHEntry *) v);
644                         VertDataCopy(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize), vertData, ss);
645                         v->flags = Vert_eEffected | Vert_eChanged | seamflag;
646                 }
647                 else {
648                         *prevp = v->next;
649                         ccg_ehash_insert(ss->vMap, (EHEntry *) v);
650                         v->flags = 0;
651                 }
652 #ifdef WITH_OPENSUBDIV
653                 v->osd_index = ss->vMap->numEntries - 1;
654 #endif
655         }
656
657         if (v_r) *v_r = v;
658         return eCCGError_None;
659 }
660
661 CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r)
662 {
663         void **prevp;
664         CCGEdge *e = NULL, *eNew;
665
666         if (ss->syncState == eSyncState_Partial) {
667                 e = ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp);
668                 if (!e || e->v0->vHDL != e_vHDL0 || e->v1->vHDL != e_vHDL1 || crease != e->crease) {
669                         CCGVert *v0 = ccg_ehash_lookup(ss->vMap, e_vHDL0);
670                         CCGVert *v1 = ccg_ehash_lookup(ss->vMap, e_vHDL1);
671
672                         eNew = _edge_new(eHDL, v0, v1, crease, ss);
673
674                         if (e) {
675                                 *prevp = eNew;
676                                 eNew->next = e->next;
677
678                                 _edge_unlinkMarkAndFree(e, ss);
679                         }
680                         else {
681                                 ccg_ehash_insert(ss->eMap, (EHEntry *) eNew);
682                         }
683
684                         eNew->v0->flags |= Vert_eEffected;
685                         eNew->v1->flags |= Vert_eEffected;
686                 }
687         }
688         else {
689                 if (ss->syncState == eSyncState_Vert) {
690                         ss->syncState = eSyncState_Edge;
691                 }
692                 else if (ss->syncState != eSyncState_Edge) {
693                         return eCCGError_InvalidSyncState;
694                 }
695
696                 e = ccg_ehash_lookupWithPrev(ss->oldEMap, eHDL, &prevp);
697                 if (!e || e->v0->vHDL != e_vHDL0 || e->v1->vHDL != e_vHDL1 || e->crease != crease) {
698                         CCGVert *v0 = ccg_ehash_lookup(ss->vMap, e_vHDL0);
699                         CCGVert *v1 = ccg_ehash_lookup(ss->vMap, e_vHDL1);
700                         e = _edge_new(eHDL, v0, v1, crease, ss);
701                         ccg_ehash_insert(ss->eMap, (EHEntry *) e);
702                         e->v0->flags |= Vert_eEffected;
703                         e->v1->flags |= Vert_eEffected;
704                 }
705                 else {
706                         *prevp = e->next;
707                         ccg_ehash_insert(ss->eMap, (EHEntry *) e);
708                         e->flags = 0;
709                         if ((e->v0->flags | e->v1->flags) & Vert_eChanged) {
710                                 e->v0->flags |= Vert_eEffected;
711                                 e->v1->flags |= Vert_eEffected;
712                         }
713                 }
714         }
715
716         if (e_r) *e_r = e;
717         return eCCGError_None;
718 }
719
720 CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r)
721 {
722         void **prevp;
723         CCGFace *f = NULL, *fNew;
724         int j, k, topologyChanged = 0;
725
726         if (UNLIKELY(numVerts > ss->lenTempArrays)) {
727                 ss->lenTempArrays = (numVerts < ss->lenTempArrays * 2) ? ss->lenTempArrays * 2 : numVerts;
728                 ss->tempVerts = MEM_reallocN(ss->tempVerts, sizeof(*ss->tempVerts) * ss->lenTempArrays);
729                 ss->tempEdges = MEM_reallocN(ss->tempEdges, sizeof(*ss->tempEdges) * ss->lenTempArrays);
730         }
731
732         if (ss->syncState == eSyncState_Partial) {
733                 f = ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp);
734
735                 for (k = 0; k < numVerts; k++) {
736                         ss->tempVerts[k] = ccg_ehash_lookup(ss->vMap, vHDLs[k]);
737                 }
738                 for (k = 0; k < numVerts; k++) {
739                         ss->tempEdges[k] = _vert_findEdgeTo(ss->tempVerts[k], ss->tempVerts[(k + 1) % numVerts]);
740                 }
741
742                 if (f) {
743                         if (f->numVerts != numVerts ||
744                             memcmp(FACE_getVerts(f), ss->tempVerts, sizeof(*ss->tempVerts) * numVerts) ||
745                             memcmp(FACE_getEdges(f), ss->tempEdges, sizeof(*ss->tempEdges) * numVerts))
746                         {
747                                 topologyChanged = 1;
748                         }
749                 }
750
751                 if (!f || topologyChanged) {
752                         fNew = _face_new(fHDL, ss->tempVerts, ss->tempEdges, numVerts, ss);
753
754                         if (f) {
755                                 ss->numGrids += numVerts - f->numVerts;
756
757                                 *prevp = fNew;
758                                 fNew->next = f->next;
759
760                                 _face_unlinkMarkAndFree(f, ss);
761                         }
762                         else {
763                                 ss->numGrids += numVerts;
764                                 ccg_ehash_insert(ss->fMap, (EHEntry *) fNew);
765                         }
766
767                         for (k = 0; k < numVerts; k++)
768                                 FACE_getVerts(fNew)[k]->flags |= Vert_eEffected;
769                 }
770         }
771         else {
772                 if (ss->syncState == eSyncState_Vert || ss->syncState == eSyncState_Edge) {
773                         ss->syncState = eSyncState_Face;
774                 }
775                 else if (ss->syncState != eSyncState_Face) {
776                         return eCCGError_InvalidSyncState;
777                 }
778
779                 f = ccg_ehash_lookupWithPrev(ss->oldFMap, fHDL, &prevp);
780
781                 for (k = 0; k < numVerts; k++) {
782                         ss->tempVerts[k] = ccg_ehash_lookup(ss->vMap, vHDLs[k]);
783
784                         if (!ss->tempVerts[k])
785                                 return eCCGError_InvalidValue;
786                 }
787                 for (k = 0; k < numVerts; k++) {
788                         ss->tempEdges[k] = _vert_findEdgeTo(ss->tempVerts[k], ss->tempVerts[(k + 1) % numVerts]);
789
790                         if (!ss->tempEdges[k]) {
791                                 if (ss->allowEdgeCreation) {
792                                         CCGEdge *e = ss->tempEdges[k] = _edge_new((CCGEdgeHDL) - 1, ss->tempVerts[k], ss->tempVerts[(k + 1) % numVerts], ss->defaultCreaseValue, ss);
793                                         ccg_ehash_insert(ss->eMap, (EHEntry *) e);
794                                         e->v0->flags |= Vert_eEffected;
795                                         e->v1->flags |= Vert_eEffected;
796                                         if (ss->meshIFC.edgeUserSize) {
797                                                 memcpy(ccgSubSurf_getEdgeUserData(ss, e), ss->defaultEdgeUserData, ss->meshIFC.edgeUserSize);
798                                         }
799                                 }
800                                 else {
801                                         return eCCGError_InvalidValue;
802                                 }
803                         }
804                 }
805
806                 if (f) {
807                         if (f->numVerts != numVerts ||
808                             memcmp(FACE_getVerts(f), ss->tempVerts, sizeof(*ss->tempVerts) * numVerts) ||
809                             memcmp(FACE_getEdges(f), ss->tempEdges, sizeof(*ss->tempEdges) * numVerts))
810                         {
811                                 topologyChanged = 1;
812                         }
813                 }
814
815                 if (!f || topologyChanged) {
816                         f = _face_new(fHDL, ss->tempVerts, ss->tempEdges, numVerts, ss);
817                         ccg_ehash_insert(ss->fMap, (EHEntry *) f);
818                         ss->numGrids += numVerts;
819
820                         for (k = 0; k < numVerts; k++)
821                                 FACE_getVerts(f)[k]->flags |= Vert_eEffected;
822                 }
823                 else {
824                         *prevp = f->next;
825                         ccg_ehash_insert(ss->fMap, (EHEntry *) f);
826                         f->flags = 0;
827                         ss->numGrids += f->numVerts;
828
829                         for (j = 0; j < f->numVerts; j++) {
830                                 if (FACE_getVerts(f)[j]->flags & Vert_eChanged) {
831                                         for (k = 0; k < f->numVerts; k++)
832                                                 FACE_getVerts(f)[k]->flags |= Vert_eEffected;
833                                         break;
834                                 }
835                         }
836                 }
837 #ifdef WITH_OPENSUBDIV
838                 f->osd_index = ss->osd_next_face_ptex_index;
839                 if (numVerts == 4) {
840                         ss->osd_next_face_ptex_index++;
841                 }
842                 else {
843                         ss->osd_next_face_ptex_index += numVerts;
844                 }
845 #endif
846         }
847
848         if (f_r) *f_r = f;
849         return eCCGError_None;
850 }
851
852 static void ccgSubSurf__sync(CCGSubSurf *ss)
853 {
854 #ifdef WITH_OPENSUBDIV
855         if (ss->skip_grids) {
856                 ccgSubSurf__sync_opensubdiv(ss);
857         }
858         else
859 #endif
860         {
861                 ccgSubSurf__sync_legacy(ss);
862         }
863 }
864
865 CCGError ccgSubSurf_processSync(CCGSubSurf *ss)
866 {
867         if (ss->syncState == eSyncState_Partial) {
868                 ss->syncState = eSyncState_None;
869
870                 ccgSubSurf__sync(ss);
871         }
872         else if (ss->syncState) {
873                 ccg_ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_unlinkMarkAndFree, ss);
874                 ccg_ehash_free(ss->oldEMap, (EHEntryFreeFP) _edge_unlinkMarkAndFree, ss);
875                 ccg_ehash_free(ss->oldVMap, (EHEntryFreeFP) _vert_free, ss);
876                 MEM_freeN(ss->tempEdges);
877                 MEM_freeN(ss->tempVerts);
878
879                 ss->lenTempArrays = 0;
880
881                 ss->oldFMap = ss->oldEMap = ss->oldVMap = NULL;
882                 ss->tempVerts = NULL;
883                 ss->tempEdges = NULL;
884
885                 ss->syncState = eSyncState_None;
886
887                 ccgSubSurf__sync(ss);
888         }
889         else {
890                 return eCCGError_InvalidSyncState;
891         }
892
893         return eCCGError_None;
894 }
895
896 void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces)
897 {
898         CCGFace **array;
899         int i, num;
900
901         if (*faces == NULL) {
902                 array = MEM_mallocN(sizeof(*array) * ss->fMap->numEntries, "CCGSubsurf allFaces");
903                 num = 0;
904                 for (i = 0; i < ss->fMap->curSize; i++) {
905                         CCGFace *f = (CCGFace *) ss->fMap->buckets[i];
906
907                         for (; f; f = f->next)
908                                 array[num++] = f;
909                 }
910
911                 *faces = array;
912                 *numFaces = num;
913                 *freeFaces = 1;
914         }
915         else {
916                 *freeFaces = 0;
917         }
918 }
919
920 void ccgSubSurf__effectedFaceNeighbours(CCGSubSurf *ss, CCGFace **faces, int numFaces, CCGVert ***verts, int *numVerts, CCGEdge ***edges, int *numEdges)
921 {
922         CCGVert **arrayV;
923         CCGEdge **arrayE;
924         int numV, numE, i, j;
925
926         arrayV = MEM_mallocN(sizeof(*arrayV) * ss->vMap->numEntries, "CCGSubsurf arrayV");
927         arrayE = MEM_mallocN(sizeof(*arrayE) * ss->eMap->numEntries, "CCGSubsurf arrayV");
928         numV = numE = 0;
929
930         for (i = 0; i < numFaces; i++) {
931                 CCGFace *f = faces[i];
932                 f->flags |= Face_eEffected;
933         }
934
935         for (i = 0; i < ss->vMap->curSize; i++) {
936                 CCGVert *v = (CCGVert *) ss->vMap->buckets[i];
937
938                 for (; v; v = v->next) {
939                         for (j = 0; j < v->numFaces; j++)
940                                 if (!(v->faces[j]->flags & Face_eEffected))
941                                         break;
942
943                         if (j == v->numFaces) {
944                                 arrayV[numV++] = v;
945                                 v->flags |= Vert_eEffected;
946                         }
947                 }
948         }
949
950         for (i = 0; i < ss->eMap->curSize; i++) {
951                 CCGEdge *e = (CCGEdge *) ss->eMap->buckets[i];
952
953                 for (; e; e = e->next) {
954                         for (j = 0; j < e->numFaces; j++)
955                                 if (!(e->faces[j]->flags & Face_eEffected))
956                                         break;
957
958                         if (j == e->numFaces) {
959                                 e->flags |= Edge_eEffected;
960                                 arrayE[numE++] = e;
961                         }
962                 }
963         }
964
965         *verts = arrayV;
966         *numVerts = numV;
967         *edges = arrayE;
968         *numEdges = numE;
969 }
970
971 /* copy face grid coordinates to other places */
972 CCGError ccgSubSurf_updateFromFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
973 {
974         int i, S, x, gridSize, cornerIdx, subdivLevels;
975         int vertDataSize = ss->meshIFC.vertDataSize, freeF;
976
977         subdivLevels = ss->subdivLevels;
978         lvl = (lvl) ? lvl : subdivLevels;
979         gridSize = ccg_gridsize(lvl);
980         cornerIdx = gridSize - 1;
981
982         ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
983
984         for (i = 0; i < numEffectedF; i++) {
985                 CCGFace *f = effectedF[i];
986
987                 for (S = 0; S < f->numVerts; S++) {
988                         CCGEdge *e = FACE_getEdges(f)[S];
989                         CCGEdge *prevE = FACE_getEdges(f)[(S + f->numVerts - 1) % f->numVerts];
990
991                         VertDataCopy((float *)FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0), ss);
992                         VertDataCopy(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), ss);
993
994                         for (x = 0; x < gridSize; x++)
995                                 VertDataCopy(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0), ss);
996
997                         for (x = 0; x < gridSize; x++) {
998                                 int eI = gridSize - 1 - x;
999                                 VertDataCopy(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x), ss);
1000                                 VertDataCopy(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx), ss);
1001                         }
1002                 }
1003         }
1004
1005         if (freeF) MEM_freeN(effectedF);
1006
1007         return eCCGError_None;
1008 }
1009
1010 /* copy other places to face grid coordinates */
1011 CCGError ccgSubSurf_updateToFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
1012 {
1013         int i, S, x, gridSize, cornerIdx, subdivLevels;
1014         int vertDataSize = ss->meshIFC.vertDataSize, freeF;
1015
1016         subdivLevels = ss->subdivLevels;
1017         lvl = (lvl) ? lvl : subdivLevels;
1018         gridSize = ccg_gridsize(lvl);
1019         cornerIdx = gridSize - 1;
1020
1021         ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
1022
1023         for (i = 0; i < numEffectedF; i++) {
1024                 CCGFace *f = effectedF[i];
1025
1026                 for (S = 0; S < f->numVerts; S++) {
1027                         int prevS = (S + f->numVerts - 1) % f->numVerts;
1028                         CCGEdge *e = FACE_getEdges(f)[S];
1029                         CCGEdge *prevE = FACE_getEdges(f)[prevS];
1030
1031                         for (x = 0; x < gridSize; x++) {
1032                                 int eI = gridSize - 1 - x;
1033                                 VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss);
1034                                 VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss);
1035                         }
1036
1037                         for (x = 1; x < gridSize - 1; x++) {
1038                                 VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x), ss);
1039                                 VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x), ss);
1040                         }
1041
1042                         VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), (float *)FACE_getCenterData(f), ss);
1043                         VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl), ss);
1044                 }
1045         }
1046
1047         if (freeF) MEM_freeN(effectedF);
1048
1049         return eCCGError_None;
1050 }
1051
1052 /* stitch together face grids, averaging coordinates at edges
1053  * and vertices, for multires displacements */
1054 CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
1055 {
1056         CCGVert **effectedV;
1057         CCGEdge **effectedE;
1058         int numEffectedV, numEffectedE, freeF;
1059         int i, S, x, gridSize, cornerIdx, subdivLevels, edgeSize;
1060         int vertDataSize = ss->meshIFC.vertDataSize;
1061
1062         subdivLevels = ss->subdivLevels;
1063         lvl = (lvl) ? lvl : subdivLevels;
1064         gridSize = ccg_gridsize(lvl);
1065         edgeSize = ccg_edgesize(lvl);
1066         cornerIdx = gridSize - 1;
1067
1068         ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
1069         ccgSubSurf__effectedFaceNeighbours(ss, effectedF, numEffectedF,
1070                                            &effectedV, &numEffectedV, &effectedE, &numEffectedE);
1071
1072         /* zero */
1073         for (i = 0; i < numEffectedV; i++) {
1074                 CCGVert *v = effectedV[i];
1075                 if (v->numFaces)
1076                         VertDataZero(VERT_getCo(v, lvl), ss);
1077         }
1078
1079         for (i = 0; i < numEffectedE; i++) {
1080                 CCGEdge *e = effectedE[i];
1081
1082                 if (e->numFaces)
1083                         for (x = 0; x < edgeSize; x++)
1084                                 VertDataZero(EDGE_getCo(e, lvl, x), ss);
1085         }
1086
1087         /* add */
1088         for (i = 0; i < numEffectedF; i++) {
1089                 CCGFace *f = effectedF[i];
1090
1091                 VertDataZero((float *)FACE_getCenterData(f), ss);
1092
1093                 for (S = 0; S < f->numVerts; S++)
1094                         for (x = 0; x < gridSize; x++)
1095                                 VertDataZero(FACE_getIECo(f, lvl, S, x), ss);
1096
1097                 for (S = 0; S < f->numVerts; S++) {
1098                         int prevS = (S + f->numVerts - 1) % f->numVerts;
1099                         CCGEdge *e = FACE_getEdges(f)[S];
1100                         CCGEdge *prevE = FACE_getEdges(f)[prevS];
1101
1102                         VertDataAdd((float *)FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0), ss);
1103                         if (FACE_getVerts(f)[S]->flags & Vert_eEffected)
1104                                 VertDataAdd(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), ss);
1105
1106                         for (x = 1; x < gridSize - 1; x++) {
1107                                 VertDataAdd(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0), ss);
1108                                 VertDataAdd(FACE_getIECo(f, lvl, prevS, x), FACE_getIFCo(f, lvl, S, 0, x), ss);
1109                         }
1110
1111                         for (x = 0; x < gridSize - 1; x++) {
1112                                 int eI = gridSize - 1 - x;
1113                                 if (FACE_getEdges(f)[S]->flags & Edge_eEffected)
1114                                         VertDataAdd(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x), ss);
1115                                 if (FACE_getEdges(f)[prevS]->flags & Edge_eEffected)
1116                                         if (x != 0)
1117                                                 VertDataAdd(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx), ss);
1118                         }
1119                 }
1120         }
1121
1122         /* average */
1123         for (i = 0; i < numEffectedV; i++) {
1124                 CCGVert *v = effectedV[i];
1125                 if (v->numFaces)
1126                         VertDataMulN(VERT_getCo(v, lvl), 1.0f / v->numFaces, ss);
1127         }
1128
1129         for (i = 0; i < numEffectedE; i++) {
1130                 CCGEdge *e = effectedE[i];
1131
1132                 VertDataCopy(EDGE_getCo(e, lvl, 0), VERT_getCo(e->v0, lvl), ss);
1133                 VertDataCopy(EDGE_getCo(e, lvl, edgeSize - 1), VERT_getCo(e->v1, lvl), ss);
1134
1135                 if (e->numFaces)
1136                         for (x = 1; x < edgeSize - 1; x++)
1137                                 VertDataMulN(EDGE_getCo(e, lvl, x), 1.0f / e->numFaces, ss);
1138         }
1139
1140         /* copy */
1141         for (i = 0; i < numEffectedF; i++) {
1142                 CCGFace *f = effectedF[i];
1143
1144                 VertDataMulN((float *)FACE_getCenterData(f), 1.0f / f->numVerts, ss);
1145
1146                 for (S = 0; S < f->numVerts; S++)
1147                         for (x = 1; x < gridSize - 1; x++)
1148                                 VertDataMulN(FACE_getIECo(f, lvl, S, x), 0.5f, ss);
1149
1150                 for (S = 0; S < f->numVerts; S++) {
1151                         int prevS = (S + f->numVerts - 1) % f->numVerts;
1152                         CCGEdge *e = FACE_getEdges(f)[S];
1153                         CCGEdge *prevE = FACE_getEdges(f)[prevS];
1154
1155                         VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), (float *)FACE_getCenterData(f), ss);
1156                         VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl), ss);
1157
1158                         for (x = 1; x < gridSize - 1; x++) {
1159                                 VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x), ss);
1160                                 VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x), ss);
1161                         }
1162
1163                         for (x = 0; x < gridSize - 1; x++) {
1164                                 int eI = gridSize - 1 - x;
1165
1166                                 VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss);
1167                                 VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss);
1168                         }
1169
1170                         VertDataCopy(FACE_getIECo(f, lvl, S, 0), (float *)FACE_getCenterData(f), ss);
1171                         VertDataCopy(FACE_getIECo(f, lvl, S, gridSize - 1), FACE_getIFCo(f, lvl, S, gridSize - 1, 0), ss);
1172                 }
1173         }
1174
1175         for (i = 0; i < numEffectedV; i++)
1176                 effectedV[i]->flags = 0;
1177         for (i = 0; i < numEffectedE; i++)
1178                 effectedE[i]->flags = 0;
1179         for (i = 0; i < numEffectedF; i++)
1180                 effectedF[i]->flags = 0;
1181
1182         MEM_freeN(effectedE);
1183         MEM_freeN(effectedV);
1184         if (freeF) MEM_freeN(effectedF);
1185
1186         return eCCGError_None;
1187 }
1188
1189 /*** External API accessor functions ***/
1190
1191 int ccgSubSurf_getNumVerts(const CCGSubSurf *ss)
1192 {
1193         return ss->vMap->numEntries;
1194 }
1195 int ccgSubSurf_getNumEdges(const CCGSubSurf *ss)
1196 {
1197         return ss->eMap->numEntries;
1198 }
1199 int ccgSubSurf_getNumFaces(const CCGSubSurf *ss)
1200 {
1201         return ss->fMap->numEntries;
1202 }
1203
1204 CCGVert *ccgSubSurf_getVert(CCGSubSurf *ss, CCGVertHDL v)
1205 {
1206         return (CCGVert *) ccg_ehash_lookup(ss->vMap, v);
1207 }
1208 CCGEdge *ccgSubSurf_getEdge(CCGSubSurf *ss, CCGEdgeHDL e)
1209 {
1210         return (CCGEdge *) ccg_ehash_lookup(ss->eMap, e);
1211 }
1212 CCGFace *ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f)
1213 {
1214         return (CCGFace *) ccg_ehash_lookup(ss->fMap, f);
1215 }
1216
1217 int ccgSubSurf_getSubdivisionLevels(const CCGSubSurf *ss)
1218 {
1219         return ss->subdivLevels;
1220 }
1221 int ccgSubSurf_getEdgeSize(const CCGSubSurf *ss)
1222 {
1223         return ccgSubSurf_getEdgeLevelSize(ss, ss->subdivLevels);
1224 }
1225 int ccgSubSurf_getEdgeLevelSize(const CCGSubSurf *ss, int level)
1226 {
1227         if (level < 1 || level > ss->subdivLevels) {
1228                 return -1;
1229         }
1230         else {
1231                 return ccg_edgesize(level);
1232         }
1233 }
1234 int ccgSubSurf_getGridSize(const CCGSubSurf *ss)
1235 {
1236         return ccgSubSurf_getGridLevelSize(ss, ss->subdivLevels);
1237 }
1238 int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level)
1239 {
1240         if (level < 1 || level > ss->subdivLevels) {
1241                 return -1;
1242         }
1243         else {
1244                 return ccg_gridsize(level);
1245         }
1246 }
1247
1248 int ccgSubSurf_getSimpleSubdiv(const CCGSubSurf *ss)
1249 {
1250         return ss->meshIFC.simpleSubdiv;
1251 }
1252
1253 /* Vert accessors */
1254
1255 CCGVertHDL ccgSubSurf_getVertVertHandle(CCGVert *v)
1256 {
1257         return v->vHDL;
1258 }
1259 int ccgSubSurf_getVertAge(CCGSubSurf *ss, CCGVert *v)
1260 {
1261         if (ss->useAgeCounts) {
1262                 byte *userData = ccgSubSurf_getVertUserData(ss, v);
1263                 return ss->currentAge - *((int *) &userData[ss->vertUserAgeOffset]);
1264         }
1265         else {
1266                 return 0;
1267         }
1268 }
1269 void *ccgSubSurf_getVertUserData(CCGSubSurf *ss, CCGVert *v)
1270 {
1271         return VERT_getLevelData(v) + ss->meshIFC.vertDataSize * (ss->subdivLevels + 1);
1272 }
1273 int ccgSubSurf_getVertNumFaces(CCGVert *v)
1274 {
1275         return v->numFaces;
1276 }
1277 CCGFace *ccgSubSurf_getVertFace(CCGVert *v, int index)
1278 {
1279         if (index < 0 || index >= v->numFaces) {
1280                 return NULL;
1281         }
1282         else {
1283                 return v->faces[index];
1284         }
1285 }
1286 int ccgSubSurf_getVertNumEdges(CCGVert *v)
1287 {
1288         return v->numEdges;
1289 }
1290 CCGEdge *ccgSubSurf_getVertEdge(CCGVert *v, int index)
1291 {
1292         if (index < 0 || index >= v->numEdges) {
1293                 return NULL;
1294         }
1295         else {
1296                 return v->edges[index];
1297         }
1298 }
1299 void *ccgSubSurf_getVertData(CCGSubSurf *ss, CCGVert *v)
1300 {
1301         return ccgSubSurf_getVertLevelData(ss, v, ss->subdivLevels);
1302 }
1303 void *ccgSubSurf_getVertLevelData(CCGSubSurf *ss, CCGVert *v, int level)
1304 {
1305         if (level < 0 || level > ss->subdivLevels) {
1306                 return NULL;
1307         }
1308         else {
1309                 return ccg_vert_getCo(v, level, ss->meshIFC.vertDataSize);
1310         }
1311 }
1312
1313 /* Edge accessors */
1314
1315 CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle(CCGEdge *e)
1316 {
1317         return e->eHDL;
1318 }
1319 int ccgSubSurf_getEdgeAge(CCGSubSurf *ss, CCGEdge *e)
1320 {
1321         if (ss->useAgeCounts) {
1322                 byte *userData = ccgSubSurf_getEdgeUserData(ss, e);
1323                 return ss->currentAge - *((int *) &userData[ss->edgeUserAgeOffset]);
1324         }
1325         else {
1326                 return 0;
1327         }
1328 }
1329 void *ccgSubSurf_getEdgeUserData(CCGSubSurf *ss, CCGEdge *e)
1330 {
1331         return (EDGE_getLevelData(e) +
1332                 ss->meshIFC.vertDataSize * ccg_edgebase(ss->subdivLevels + 1));
1333 }
1334 int ccgSubSurf_getEdgeNumFaces(CCGEdge *e)
1335 {
1336         return e->numFaces;
1337 }
1338 CCGFace *ccgSubSurf_getEdgeFace(CCGEdge *e, int index)
1339 {
1340         if (index < 0 || index >= e->numFaces) {
1341                 return NULL;
1342         }
1343         else {
1344                 return e->faces[index];
1345         }
1346 }
1347 CCGVert *ccgSubSurf_getEdgeVert0(CCGEdge *e)
1348 {
1349         return e->v0;
1350 }
1351 CCGVert *ccgSubSurf_getEdgeVert1(CCGEdge *e)
1352 {
1353         return e->v1;
1354 }
1355 void *ccgSubSurf_getEdgeDataArray(CCGSubSurf *ss, CCGEdge *e)
1356 {
1357         return ccgSubSurf_getEdgeData(ss, e, 0);
1358 }
1359 void *ccgSubSurf_getEdgeData(CCGSubSurf *ss, CCGEdge *e, int x)
1360 {
1361         return ccgSubSurf_getEdgeLevelData(ss, e, x, ss->subdivLevels);
1362 }
1363 void *ccgSubSurf_getEdgeLevelData(CCGSubSurf *ss, CCGEdge *e, int x, int level)
1364 {
1365         if (level < 0 || level > ss->subdivLevels) {
1366                 return NULL;
1367         }
1368         else {
1369                 return ccg_edge_getCo(e, level, x, ss->meshIFC.vertDataSize);
1370         }
1371 }
1372 float ccgSubSurf_getEdgeCrease(CCGEdge *e)
1373 {
1374         return e->crease;
1375 }
1376
1377 /* Face accessors */
1378
1379 CCGFaceHDL ccgSubSurf_getFaceFaceHandle(CCGFace *f)
1380 {
1381         return f->fHDL;
1382 }
1383 int ccgSubSurf_getFaceAge(CCGSubSurf *ss, CCGFace *f)
1384 {
1385         if (ss->useAgeCounts) {
1386                 byte *userData = ccgSubSurf_getFaceUserData(ss, f);
1387                 return ss->currentAge - *((int *) &userData[ss->faceUserAgeOffset]);
1388         }
1389         else {
1390                 return 0;
1391         }
1392 }
1393 void *ccgSubSurf_getFaceUserData(CCGSubSurf *ss, CCGFace *f)
1394 {
1395         int maxGridSize = ccg_gridsize(ss->subdivLevels);
1396         return FACE_getCenterData(f) + ss->meshIFC.vertDataSize * (1 + f->numVerts * maxGridSize + f->numVerts * maxGridSize * maxGridSize);
1397 }
1398 int ccgSubSurf_getFaceNumVerts(CCGFace *f)
1399 {
1400         return f->numVerts;
1401 }
1402 CCGVert *ccgSubSurf_getFaceVert(CCGFace *f, int index)
1403 {
1404         if (index < 0 || index >= f->numVerts) {
1405                 return NULL;
1406         }
1407         else {
1408                 return FACE_getVerts(f)[index];
1409         }
1410 }
1411 CCGEdge *ccgSubSurf_getFaceEdge(CCGFace *f, int index)
1412 {
1413         if (index < 0 || index >= f->numVerts) {
1414                 return NULL;
1415         }
1416         else {
1417                 return FACE_getEdges(f)[index];
1418         }
1419 }
1420 int ccgSubSurf_getFaceEdgeIndex(CCGFace *f, CCGEdge *e)
1421 {
1422         int i;
1423
1424         for (i = 0; i < f->numVerts; i++) {
1425                 if (FACE_getEdges(f)[i] == e) {
1426                         return i;
1427                 }
1428         }
1429         return -1;
1430 }
1431 void *ccgSubSurf_getFaceCenterData(CCGFace *f)
1432 {
1433         return FACE_getCenterData(f);
1434 }
1435 void *ccgSubSurf_getFaceGridEdgeDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex)
1436 {
1437         return ccgSubSurf_getFaceGridEdgeData(ss, f, gridIndex, 0);
1438 }
1439 void *ccgSubSurf_getFaceGridEdgeData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x)
1440 {
1441         return ccg_face_getIECo(f, ss->subdivLevels, gridIndex, x, ss->subdivLevels, ss->meshIFC.vertDataSize);
1442 }
1443 void *ccgSubSurf_getFaceGridDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex)
1444 {
1445         return ccgSubSurf_getFaceGridData(ss, f, gridIndex, 0, 0);
1446 }
1447 void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y)
1448 {
1449         return ccg_face_getIFCo(f, ss->subdivLevels, gridIndex, x, y, ss->subdivLevels, ss->meshIFC.vertDataSize);
1450 }
1451
1452 /*** External API iterator functions ***/
1453
1454 void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter)
1455 {
1456         ccg_ehashIterator_init(ss->vMap, viter);
1457 }
1458 void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter)
1459 {
1460         ccg_ehashIterator_init(ss->eMap, eiter);
1461 }
1462 void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter)
1463 {
1464         ccg_ehashIterator_init(ss->fMap, fiter);
1465 }
1466
1467 CCGVert *ccgVertIterator_getCurrent(CCGVertIterator *vi)
1468 {
1469         return (CCGVert *) ccg_ehashIterator_getCurrent((EHashIterator *) vi);
1470 }
1471 int ccgVertIterator_isStopped(CCGVertIterator *vi)
1472 {
1473         return ccg_ehashIterator_isStopped((EHashIterator *) vi);
1474 }
1475 void ccgVertIterator_next(CCGVertIterator *vi)
1476 {
1477         ccg_ehashIterator_next((EHashIterator *) vi);
1478 }
1479
1480 CCGEdge *ccgEdgeIterator_getCurrent(CCGEdgeIterator *vi)
1481 {
1482         return (CCGEdge *) ccg_ehashIterator_getCurrent((EHashIterator *) vi);
1483 }
1484 int ccgEdgeIterator_isStopped(CCGEdgeIterator *vi)
1485 {
1486         return ccg_ehashIterator_isStopped((EHashIterator *) vi);
1487 }
1488 void ccgEdgeIterator_next(CCGEdgeIterator *vi)
1489 {
1490         ccg_ehashIterator_next((EHashIterator *) vi);
1491 }
1492
1493 CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *vi)
1494 {
1495         return (CCGFace *) ccg_ehashIterator_getCurrent((EHashIterator *) vi);
1496 }
1497 int ccgFaceIterator_isStopped(CCGFaceIterator *vi)
1498 {
1499         return ccg_ehashIterator_isStopped((EHashIterator *) vi);
1500 }
1501 void ccgFaceIterator_next(CCGFaceIterator *vi)
1502 {
1503         ccg_ehashIterator_next((EHashIterator *) vi);
1504 }
1505
1506 /*** Extern API final vert/edge/face interface ***/
1507
1508 int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss)
1509 {
1510         int edgeSize = ccg_edgesize(ss->subdivLevels);
1511         int gridSize = ccg_gridsize(ss->subdivLevels);
1512         int numFinalVerts = (ss->vMap->numEntries +
1513                              ss->eMap->numEntries * (edgeSize - 2) +
1514                              ss->fMap->numEntries +
1515                              ss->numGrids * ((gridSize - 2) + ((gridSize - 2) * (gridSize - 2))));
1516
1517 #ifdef WITH_OPENSUBDIV
1518         if (ss->skip_grids) {
1519                 return 0;
1520         }
1521 #endif
1522
1523         return numFinalVerts;
1524 }
1525 int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss)
1526 {
1527         int edgeSize = ccg_edgesize(ss->subdivLevels);
1528         int gridSize = ccg_gridsize(ss->subdivLevels);
1529         int numFinalEdges = (ss->eMap->numEntries * (edgeSize - 1) +
1530                              ss->numGrids * ((gridSize - 1) + 2 * ((gridSize - 2) * (gridSize - 1))));
1531 #ifdef WITH_OPENSUBDIV
1532         if (ss->skip_grids) {
1533                 return 0;
1534         }
1535 #endif
1536         return numFinalEdges;
1537 }
1538 int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss)
1539 {
1540         int gridSize = ccg_gridsize(ss->subdivLevels);
1541         int numFinalFaces = ss->numGrids * ((gridSize - 1) * (gridSize - 1));
1542 #ifdef WITH_OPENSUBDIV
1543         if (ss->skip_grids) {
1544                 return 0;
1545         }
1546 #endif
1547         return numFinalFaces;
1548 }
1549
1550 /***/
1551
1552 void CCG_key(CCGKey *key, const CCGSubSurf *ss, int level)
1553 {
1554         key->level = level;
1555
1556         key->elem_size = ss->meshIFC.vertDataSize;
1557         key->has_normals = ss->calcVertNormals;
1558
1559         /* if normals are present, always the last three floats of an
1560          * element */
1561         if (key->has_normals)
1562                 key->normal_offset = key->elem_size - sizeof(float) * 3;
1563         else
1564                 key->normal_offset = -1;
1565
1566         key->grid_size = ccgSubSurf_getGridLevelSize(ss, level);
1567         key->grid_area = key->grid_size * key->grid_size;
1568         key->grid_bytes = key->elem_size * key->grid_area;
1569
1570         key->has_mask = ss->allocMask;
1571         if (key->has_mask)
1572                 key->mask_offset = ss->maskDataOffset;
1573         else
1574                 key->mask_offset = -1;
1575 }
1576
1577 void CCG_key_top_level(CCGKey *key, const CCGSubSurf *ss)
1578 {
1579         CCG_key(key, ss, ccgSubSurf_getSubdivisionLevels(ss));
1580 }