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