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