svn merge ^/trunk/blender -r42303:42329
[blender-staging.git] / source / blender / blenkernel / intern / subsurf_ccg.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  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/subsurf_ccg.c
29  *  \ingroup bke
30  */
31
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <math.h>
37 #include <float.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
46
47 #include "BLI_utildefines.h"
48 #include "BLI_blenlib.h"
49 #include "BLI_edgehash.h"
50 #include "BLI_math.h"
51 #include "BLI_memarena.h"
52 #include "BLI_pbvh.h"
53
54 #include "BKE_cdderivedmesh.h"
55 #include "BKE_global.h"
56 #include "BKE_mesh.h"
57 #include "BKE_modifier.h"
58 #include "BKE_paint.h"
59 #include "BKE_scene.h"
60 #include "BKE_subsurf.h"
61 #include "BKE_tessmesh.h"
62
63 #include "PIL_time.h"
64 #include "BLI_array.h"
65
66 #include "GL/glew.h"
67
68 #include "GPU_draw.h"
69 #include "GPU_extensions.h"
70 #include "GPU_material.h"
71
72 #include "CCGSubSurf.h"
73
74 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
75
76 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
77                                          int drawInteriorEdges,
78                                          int useSubsurfUv,
79                                          DerivedMesh *dm);
80 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
81
82 ///
83
84 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
85         return BLI_memarena_alloc(a, numBytes);
86 }
87 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
88         void *p2 = BLI_memarena_alloc(a, newSize);
89         if (ptr) {
90                 memcpy(p2, ptr, oldSize);
91         }
92         return p2;
93 }
94 static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr)) {
95 }
96 static void arena_release(CCGAllocatorHDL a) {
97         BLI_memarena_free(a);
98 }
99
100 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int UNUSED(useFlatSubdiv)) {
101         CCGMeshIFC ifc;
102         CCGSubSurf *ccgSS;
103
104                 /* subdivLevels==0 is not allowed */
105         subdivLevels = MAX2(subdivLevels, 1);
106
107         if (prevSS) {
108                 int oldUseAging;
109
110                 useAging = !!useAging;
111                 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
112
113                 if (oldUseAging!=useAging) {
114                         ccgSubSurf_free(prevSS);
115                 } else {
116                         ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
117
118                         return prevSS;
119                 }
120         }
121
122         if (useAging) {
123                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
124         } else {
125                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
126         }
127         ifc.vertDataSize = sizeof(DMGridData);
128
129         if (useArena) {
130                 CCGAllocatorIFC allocatorIFC;
131                 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16), "subsurf arena");
132
133                 allocatorIFC.alloc = arena_alloc;
134                 allocatorIFC.realloc = arena_realloc;
135                 allocatorIFC.free = arena_free;
136                 allocatorIFC.release = arena_release;
137
138                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
139         } else {
140                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
141         }
142
143         if (useAging) {
144                 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
145         }
146
147         ccgSubSurf_setCalcVertexNormals(ccgSS, 1, offsetof(DMGridData, no));
148
149         return ccgSS;
150 }
151
152 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
153         CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
154         CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
155         int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
156         int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
157         int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
158
159         if (x==0) {
160                 return v0idx;
161         } else if (x==edgeSize-1) {
162                 return v1idx;
163         } else {
164                 return edgeBase + x-1;
165         }
166 }
167
168 BM_INLINE int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
169         int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
170         int numVerts = ccgSubSurf_getFaceNumVerts(f);
171
172         if (x==gridSize-1 && y==gridSize-1) {
173                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
174                 return *((int*) ccgSubSurf_getVertUserData(ss, v));
175         } else if (x==gridSize-1) {
176                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
177                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
178                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
179                 if (v==ccgSubSurf_getEdgeVert0(e)) {
180                         return edgeBase + (gridSize-1-y)-1;
181                 } else {
182                         return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
183                 }
184         } else if (y==gridSize-1) {
185                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
186                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
187                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
188                 if (v==ccgSubSurf_getEdgeVert0(e)) {
189                         return edgeBase + (gridSize-1-x)-1;
190                 } else {
191                         return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
192                 }
193         } else if (x==0 && y==0) {
194                 return faceBase;
195         } else if (x==0) {
196                 S = (S+numVerts-1)%numVerts;
197                 return faceBase + 1 + (gridSize-2)*S + (y-1);
198         } else if (y==0) {
199                 return faceBase + 1 + (gridSize-2)*S + (x-1);
200         } else {
201                 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
202         }
203 }
204
205 static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mp, struct MLoop *ml, int fi, CCGVertHDL *fverts) {
206         UvMapVert *v, *nv;
207         int j, nverts= mp->totloop;
208
209         for (j=0; j<nverts; j++) {
210                 for (nv=v=get_uv_map_vert(vmap, ml[j].v); v; v=v->next) {
211                         if (v->separate)
212                                 nv= v;
213                         if (v->f == fi)
214                                 break;
215                 }
216
217                 fverts[j]= SET_INT_IN_POINTER(nv->f*4 + nv->tfindex);
218         }
219 }
220
221 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MLoopUV *mloopuv) {
222         MPoly *mpoly = dm->getPolyArray(dm);
223         MLoop *mloop = dm->getLoopArray(dm);
224         MVert *mvert = dm->getVertArray(dm);
225         int totvert = dm->getNumVerts(dm);
226         int totface = dm->getNumPolys(dm);
227         int i, j, seam;
228         UvMapVert *v;
229         UvVertMap *vmap;
230         float limit[2];
231         CCGVertHDL *fverts= NULL;
232         BLI_array_declare(fverts);
233         EdgeHash *ehash;
234         float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
235
236         limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
237         vmap= make_uv_vert_map(mpoly, mloop, mloopuv, totface, totvert, 0, limit);
238         if (!vmap)
239                 return 0;
240         
241         ccgSubSurf_initFullSync(ss);
242
243         /* create vertices */
244         for (i=0; i<totvert; i++) {
245                 if (!get_uv_map_vert(vmap, i))
246                         continue;
247
248                 for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next)
249                         if (v->separate)
250                                 break;
251
252                 seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED);
253
254                 for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
255                         if (v->separate) {
256                                 CCGVert *ssv;
257                                 CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
258                                 float uv[3];
259
260                                 uv[0]= mloopuv[mpoly[v->f].loopstart + v->tfindex].uv[0];
261                                 uv[1]= mloopuv[mpoly[v->f].loopstart + v->tfindex].uv[1];
262                                 uv[2]= 0.0f;
263
264                                 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
265                         }
266                 }
267         }
268
269         /* create edges */
270         ehash = BLI_edgehash_new();
271
272         for (i=0; i<totface; i++) {
273                 MPoly *mp = &((MPoly*) mpoly)[i];
274                 int nverts= mp->totloop;
275                 CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i));
276                 /* unsigned int *fv = &mp->v1; */
277                 MLoop *ml= mloop + mp->loopstart;
278
279                 BLI_array_empty(fverts);
280                 BLI_array_growitems(fverts, nverts);
281
282                 get_face_uv_map_vert(vmap, mp, ml, i, fverts);
283
284                 for (j=0; j<nverts; j++) {
285                         int v0 = GET_INT_FROM_POINTER(fverts[j]);
286                         int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]);
287                         MVert *mv0 = mvert + (ml[ j ]. v);
288                         MVert *mv1 = mvert + (ml[ ((j+1)%nverts) ].v);
289
290                         if (!BLI_edgehash_haskey(ehash, v0, v1)) {
291                                 CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j);
292                                 CCGEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j);
293                                 float crease;
294
295                                 if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
296                                         crease = creaseFactor;
297                                 else
298                                         crease = ccgSubSurf_getEdgeCrease(orige);
299
300                                 ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e);
301                                 BLI_edgehash_insert(ehash, v0, v1, NULL);
302                         }
303                 }
304         }
305
306         BLI_edgehash_free(ehash, NULL);
307
308         /* create faces */
309         for (i=0; i<totface; i++) {
310                 MPoly *mp = &((MPoly*) mpoly)[i];
311                 MLoop *ml= mloop + mp->loopstart;
312                 int nverts= mp->totloop;
313                 CCGFace *f;
314
315                 BLI_array_empty(fverts);
316                 BLI_array_growitems(fverts, nverts);
317
318                 get_face_uv_map_vert(vmap, mp, ml, i, fverts);
319                 ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f);
320         }
321
322         BLI_array_free(fverts);
323
324         free_uv_vert_map(vmap);
325         ccgSubSurf_processSync(ss);
326
327         return 1;
328 }
329
330 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
331 {
332         CCGSubSurf *uvss;
333         CCGFace **faceMap;
334         MTFace *tf;
335         MLoopUV *mluv;
336         CCGFaceIterator *fi;
337         int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
338         MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
339         /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
340          * just tface except applying the modifier then looses subsurf UV */
341         MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
342         MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n);
343
344         if(!dmloopuv || (!tface && !mloopuv))
345                 return;
346
347         /* create a CCGSubSurf from uv's */
348         uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0);
349
350         if(!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) {
351                 ccgSubSurf_free(uvss);
352                 return;
353         }
354
355         /* get some info from CCGSubSurf */
356         totface = ccgSubSurf_getNumFaces(uvss);
357         /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
358         gridSize = ccgSubSurf_getGridSize(uvss);
359         gridFaces = gridSize - 1;
360
361         /* make a map from original faces to CCGFaces */
362         faceMap = MEM_mallocN(totface*sizeof(*faceMap), "facemapuv");
363
364         fi = ccgSubSurf_getFaceIterator(uvss);
365         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
366                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
367                 faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(uvss, f))] = f;
368         }
369         ccgFaceIterator_free(fi);
370
371         /* load coordinates from uvss into tface */
372         tf= tface;
373         mluv= mloopuv;
374
375         for(index = 0; index < totface; index++) {
376                 CCGFace *f = faceMap[index];
377                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
378
379                 for (S=0; S<numVerts; S++) {
380                         DMGridData *faceGridData= ccgSubSurf_getFaceGridDataArray(uvss, f, S);
381
382                         for(y = 0; y < gridFaces; y++) {
383                                 for(x = 0; x < gridFaces; x++) {
384                                         float *a = faceGridData[(y + 0)*gridSize + x + 0].co;
385                                         float *b = faceGridData[(y + 0)*gridSize + x + 1].co;
386                                         float *c = faceGridData[(y + 1)*gridSize + x + 1].co;
387                                         float *d = faceGridData[(y + 1)*gridSize + x + 0].co;
388
389                                         if (tface) {
390                                                 tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1];
391                                                 tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1];
392                                                 tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1];
393                                                 tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1];
394                                         }
395
396                                         if (mloopuv) {
397                                                 mluv[0].uv[0] = a[0]; mluv[0].uv[1] = a[1];
398                                                 mluv[1].uv[0] = d[0]; mluv[1].uv[1] = d[1];
399                                                 mluv[2].uv[0] = c[0]; mluv[2].uv[1] = c[1];
400                                                 mluv[3].uv[0] = b[0]; mluv[3].uv[1] = b[1];
401                                         }
402
403                                         tf++;
404                                         mluv+=4;
405                                 }
406                         }
407                 }
408         }
409
410         ccgSubSurf_free(uvss);
411         MEM_freeN(faceMap);
412 }
413
414 /* face weighting */
415 typedef struct FaceVertWeightEntry {
416         FaceVertWeight *weight;
417         float *w;
418         int valid;
419 } FaceVertWeightEntry;
420
421 typedef struct WeightTable {
422         FaceVertWeightEntry *weight_table;
423         int len;
424 } WeightTable;
425
426 static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
427 {
428         int x, y, i, j;
429         float *w, w1, w2, w4, fac, fac2, fx, fy;
430
431         if (wtable->len <= faceLen) {
432                 void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry)*(faceLen+1), "weight table alloc 2");
433                 
434                 if (wtable->len) {
435                         memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry)*wtable->len);
436                         MEM_freeN(wtable->weight_table);
437                 }
438                 
439                 wtable->weight_table = tmp;
440                 wtable->len = faceLen+1;
441         }
442
443         if (!wtable->weight_table[faceLen].valid) {
444                 wtable->weight_table[faceLen].valid = 1;
445                 wtable->weight_table[faceLen].w = w = MEM_callocN(sizeof(float)*faceLen*faceLen*(gridCuts+2)*(gridCuts+2), "weight table alloc");
446                 fac = 1.0f / (float)faceLen;
447
448                 for (i=0; i<faceLen; i++) {
449                         for (x=0; x<gridCuts+2; x++) {
450                                 for (y=0; y<gridCuts+2; y++) {
451                                         fx = 0.5f - (float)x / (float)(gridCuts+1) / 2.0f;
452                                         fy = 0.5f - (float)y / (float)(gridCuts+1) / 2.0f;
453                                 
454                                         fac2 = faceLen - 4;
455                                         w1 = (1.0f - fx) * (1.0f - fy) + (-fac2*fx*fy*fac);
456                                         w2 = (1.0f - fx + fac2*fx*-fac) * (fy);
457                                         w4 = (fx) * (1.0f - fy + -fac2*fy*fac);
458                                         
459                                         fac2 = 1.0f - (w1+w2+w4);
460                                         fac2 = fac2 / (float)(faceLen-3);
461                                         for (j=0; j<faceLen; j++)
462                                                 w[j] = fac2;
463                                         
464                                         w[i] = w1;
465                                         w[(i-1+faceLen)%faceLen] = w2;
466                                         w[(i+1)%faceLen] = w4;
467
468                                         w += faceLen;
469                                 }
470                         }
471                 }
472         }
473
474         return wtable->weight_table[faceLen].w;
475 }
476
477 static void free_ss_weights(WeightTable *wtable)
478 {
479         int i;
480
481         for (i=0; i<wtable->len; i++) {
482                 if (wtable->weight_table[i].valid)
483                         MEM_freeN(wtable->weight_table[i].w);
484         }
485         
486         if (wtable->weight_table)
487                 MEM_freeN(wtable->weight_table);
488 }
489
490 #if 0
491 static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
492                                                                  int drawInteriorEdges, int useSubsurfUv,
493                                                                  DerivedMesh *dm, struct MultiresSubsurf *ms)
494 {
495         DerivedMesh *cgdm, *result;
496         double curt = PIL_check_seconds_timer();
497
498         cgdm = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
499         result = CDDM_copy(cgdm, 1);
500
501         printf("subsurf conversion time: %.6lf\n", PIL_check_seconds_timer() - curt);
502
503         cgdm->needsFree = 1;
504         cgdm->release(cgdm);
505
506         CDDM_calc_normals(result);
507
508         return result;
509 }
510 #endif
511
512 static int ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
513                                                                          float (*vertexCos)[3], int useFlatSubdiv)
514 {
515         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
516         CCGVertHDL *fVerts = NULL;
517         BLI_array_declare(fVerts);
518         MVert *mvert = dm->getVertArray(dm);
519         MEdge *medge = dm->getEdgeArray(dm);
520         /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
521         MVert *mv;
522         MEdge *me;
523         MLoop *mloop = dm->getLoopArray(dm), *ml;
524         MPoly *mpoly = dm->getPolyArray(dm), *mp;
525         /*MFace *mf;*/ /*UNUSED*/
526         int totvert = dm->getNumVerts(dm);
527         int totedge = dm->getNumEdges(dm);
528         /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
529         /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/
530         int i, j;
531         int *index;
532
533         ccgSubSurf_initFullSync(ss);
534
535         mv = mvert;
536         index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
537         for(i = 0; i < totvert; i++, mv++) {
538                 CCGVert *v;
539
540                 if(vertexCos) {
541                         ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v);
542                 } else {
543                         ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v);
544                 }
545
546                 ((int*)ccgSubSurf_getVertUserData(ss, v))[1] = (index)? *index++: i;
547         }
548
549         me = medge;
550         index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
551         for(i = 0; i < totedge; i++, me++) {
552                 CCGEdge *e;
553                 float crease;
554
555                 crease = useFlatSubdiv ? creaseFactor :
556                                                                  me->crease * creaseFactor / 255.0f;
557
558                 ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1),
559                                                         SET_INT_IN_POINTER(me->v2), crease, &e);
560
561                 ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index)? *index++: i;
562         }
563
564         mp = mpoly;
565         index = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
566         for (i=0; i<dm->numPolyData; i++, mp++) {
567                 CCGFace *f=NULL;
568
569                 BLI_array_empty(fVerts);
570
571                 ml = mloop + mp->loopstart;
572                 for (j=0; j<mp->totloop; j++, ml++) {
573                         BLI_array_append(fVerts, SET_INT_IN_POINTER(ml->v));
574                 }
575
576                 /* this is very bad, means mesh is internally inconsistent.
577                  * it is not really possible to continue without modifying
578                  * other parts of code significantly to handle missing faces.
579                  * since this really shouldn't even be possible we just bail.*/
580                 if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), mp->totloop,
581                                                            fVerts, &f) == eCCGError_InvalidValue) {
582                         static int hasGivenError = 0;
583
584                         if(!hasGivenError) {
585                                 printf("Unrecoverable error in SubSurf calculation,"
586                                            " mesh is inconsistent.\n");
587
588                                 hasGivenError = 1;
589                         }
590
591                         return 0;
592                 }
593
594                 ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = index ? *index++: i;
595         }
596
597         ccgSubSurf_processSync(ss);
598
599         BLI_array_free(fVerts);
600         return 1;
601 }
602
603 /***/
604
605 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v) {
606         return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
607 }
608
609 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e) {
610         return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
611 }
612
613 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) {
614         return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
615 }
616
617 static void cgdm_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
618         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
619         CCGSubSurf *ss = cgdm->ss;
620         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
621         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
622         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
623         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
624         int gridSize = ccgSubSurf_getGridSize(ss);
625
626         if (!ccgSubSurf_getNumVerts(ss))
627                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
628
629         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
630                 CCGVert *v = ccgVertIterator_getCurrent(vi);
631                 float *co = ccgSubSurf_getVertData(ss, v);
632
633                 DO_MINMAX(co, min_r, max_r);
634         }
635
636         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
637                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
638                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
639
640                 for (i=0; i<edgeSize; i++)
641                         DO_MINMAX(edgeData[i].co, min_r, max_r);
642         }
643
644         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
645                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
646                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
647
648                 for (S=0; S<numVerts; S++) {
649                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
650
651                         for (y=0; y<gridSize; y++)
652                                 for (x=0; x<gridSize; x++)
653                                         DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
654                 }
655         }
656
657         ccgFaceIterator_free(fi);
658         ccgEdgeIterator_free(ei);
659         ccgVertIterator_free(vi);
660 }
661 static int cgdm_getNumVerts(DerivedMesh *dm) {
662         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
663
664         return ccgSubSurf_getNumFinalVerts(cgdm->ss);
665 }
666 static int cgdm_getNumEdges(DerivedMesh *dm) {
667         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
668
669         return ccgSubSurf_getNumFinalEdges(cgdm->ss);
670 }
671 static int cgdm_getNumTessFaces(DerivedMesh *dm) {
672         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
673
674         return ccgSubSurf_getNumFinalFaces(cgdm->ss);
675 }
676 static int cgdm_getNumLoops(DerivedMesh *dm) {
677         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
678
679         /* All subsurf faces are quads */
680         return 4 * ccgSubSurf_getNumFinalFaces(cgdm->ss);
681 }
682
683 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
684 {
685         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
686         CCGSubSurf *ss = cgdm->ss;
687         DMGridData *vd;
688         int i;
689
690         memset(mv, 0, sizeof(*mv));
691
692         if((vertNum < cgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
693                 /* this vert comes from face data */
694                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
695                 CCGFace *f;
696                 int x, y, grid, numVerts;
697                 int offset;
698                 int gridSize = ccgSubSurf_getGridSize(ss);
699                 int gridSideVerts;
700                 int gridInternalVerts;
701                 int gridSideEnd;
702                 int gridInternalEnd;
703
704                 i = 0;
705                 while(i < lastface && vertNum >= cgdm->faceMap[i + 1].startVert)
706                         ++i;
707
708                 f = cgdm->faceMap[i].face;
709                 numVerts = ccgSubSurf_getFaceNumVerts(f);
710
711                 gridSideVerts = gridSize - 2;
712                 gridInternalVerts = gridSideVerts * gridSideVerts;
713
714                 gridSideEnd = 1 + numVerts * gridSideVerts;
715                 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
716
717                 offset = vertNum - cgdm->faceMap[i].startVert;
718                 if(offset < 1) {
719                         vd = ccgSubSurf_getFaceCenterData(f);
720                         copy_v3_v3(mv->co, vd->co);
721                         normal_float_to_short_v3(mv->no, vd->no);
722                 } else if(offset < gridSideEnd) {
723                         offset -= 1;
724                         grid = offset / gridSideVerts;
725                         x = offset % gridSideVerts + 1;
726                         vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
727                         copy_v3_v3(mv->co, vd->co);
728                         normal_float_to_short_v3(mv->no, vd->no);
729                 } else if(offset < gridInternalEnd) {
730                         offset -= gridSideEnd;
731                         grid = offset / gridInternalVerts;
732                         offset %= gridInternalVerts;
733                         y = offset / gridSideVerts + 1;
734                         x = offset % gridSideVerts + 1;
735                         vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
736                         copy_v3_v3(mv->co, vd->co);
737                         normal_float_to_short_v3(mv->no, vd->no);
738                 }
739         } else if((vertNum < cgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
740                 /* this vert comes from edge data */
741                 CCGEdge *e;
742                 int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
743                 int x;
744
745                 i = 0;
746                 while(i < lastedge && vertNum >= cgdm->edgeMap[i + 1].startVert)
747                         ++i;
748
749                 e = cgdm->edgeMap[i].edge;
750
751                 x = vertNum - cgdm->edgeMap[i].startVert + 1;
752                 vd = ccgSubSurf_getEdgeData(ss, e, x);
753                 copy_v3_v3(mv->co, vd->co);
754                 normal_float_to_short_v3(mv->no, vd->no);
755         } else {
756                 /* this vert comes from vert data */
757                 CCGVert *v;
758                 i = vertNum - cgdm->vertMap[0].startVert;
759
760                 v = cgdm->vertMap[i].vert;
761                 vd = ccgSubSurf_getVertData(ss, v);
762                 copy_v3_v3(mv->co, vd->co);
763                 normal_float_to_short_v3(mv->no, vd->no);
764         }
765 }
766
767 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float co_r[3])
768 {
769         MVert mvert;
770
771         ccgDM_getFinalVert(dm, vertNum, &mvert);
772         copy_v3_v3(co_r, mvert.co);
773 }
774
775 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3])
776 {
777         MVert mvert;
778
779         ccgDM_getFinalVert(dm, vertNum, &mvert);
780         normal_short_to_float_v3(no_r, mvert.no);
781 }
782
783 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
784 {
785         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
786         CCGSubSurf *ss = cgdm->ss;
787         int i;
788
789         memset(med, 0, sizeof(*med));
790
791         if(edgeNum < cgdm->edgeMap[0].startEdge) {
792                 /* this edge comes from face data */
793                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
794                 CCGFace *f;
795                 int x, y, grid /*, numVerts*/;
796                 int offset;
797                 int gridSize = ccgSubSurf_getGridSize(ss);
798                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
799                 int gridSideEdges;
800                 int gridInternalEdges;
801                                 int lasti, previ;
802
803                                 i = lastface;
804                                 lasti = 0;
805                                 while (1) {
806                                         previ = i;
807                                         if (cgdm->faceMap[i].startEdge >= edgeNum) {
808                                                 i -= fabsf(i-lasti)/2.0f;
809                                         } else if (cgdm->faceMap[i].startEdge < edgeNum) {
810                                                 i += fabsf(i-lasti)/2.0f;
811                                         } else {
812                                                 break;
813                                         }
814
815                                         if (i < 0) {
816                                                 i = 0;
817                                                 break;
818                                         }
819
820                                         if (i > lastface) {
821                                                 i = lastface;
822                                                 break;
823
824                                         }
825
826                                         if (i == lasti)
827                                            break;
828
829                                         lasti = previ;
830                                 }
831
832                                 i = i > 0 ? i - 1 : i;
833                 while(i < lastface && edgeNum >= cgdm->faceMap[i + 1].startEdge)
834                         ++i;
835
836                 f = cgdm->faceMap[i].face;
837                 /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
838
839                 gridSideEdges = gridSize - 1;
840                 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
841
842                 offset = edgeNum - cgdm->faceMap[i].startEdge;
843                 grid = offset / (gridSideEdges + gridInternalEdges);
844                 offset %= (gridSideEdges + gridInternalEdges);
845
846                 if(offset < gridSideEdges) {
847                         x = offset;
848                         med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
849                         med->v2 = getFaceIndex(ss, f, grid, x+1, 0, edgeSize, gridSize);
850                 } else {
851                         offset -= gridSideEdges;
852                         x = (offset / 2) / gridSideEdges + 1;
853                         y = (offset / 2) % gridSideEdges;
854                         if(offset % 2 == 0) {
855                                 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
856                                 med->v2 = getFaceIndex(ss, f, grid, x, y+1, edgeSize, gridSize);
857                         } else {
858                                 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
859                                 med->v2 = getFaceIndex(ss, f, grid, y+1, x, edgeSize, gridSize);
860                         }
861                 }
862         } else {
863                 /* this vert comes from edge data */
864                 CCGEdge *e;
865                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
866                 int x;
867                 short *edgeFlag;
868                 unsigned int flags = 0;
869
870                 i = (edgeNum - cgdm->edgeMap[0].startEdge) / (edgeSize - 1);
871
872                 e = cgdm->edgeMap[i].edge;
873
874                 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
875
876                 x = edgeNum - cgdm->edgeMap[i].startEdge;
877
878                 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
879                 med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
880
881                 edgeFlag = (cgdm->edgeFlags)? &cgdm->edgeFlags[i]: NULL;
882                 if(edgeFlag)
883                         flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
884                                          | ME_EDGEDRAW | ME_EDGERENDER;
885                 else
886                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
887
888                 med->flag = flags;
889         }
890 }
891
892 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
893 {
894         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
895         CCGSubSurf *ss = cgdm->ss;
896         int gridSize = ccgSubSurf_getGridSize(ss);
897         int edgeSize = ccgSubSurf_getEdgeSize(ss);
898         int gridSideEdges = gridSize - 1;
899         int gridFaces = gridSideEdges * gridSideEdges;
900         int i;
901         CCGFace *f;
902         /*int numVerts;*/
903         int offset;
904         int grid;
905         int x, y;
906         /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
907         char *faceFlags = cgdm->faceFlags;
908
909         memset(mf, 0, sizeof(*mf));
910         if (faceNum >= cgdm->dm.numTessFaceData)
911                 return;
912
913         i = cgdm->reverseFaceMap[faceNum];
914
915         f = cgdm->faceMap[i].face;
916         /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
917
918         offset = faceNum - cgdm->faceMap[i].startFace;
919         grid = offset / gridFaces;
920         offset %= gridFaces;
921         y = offset / gridSideEdges;
922         x = offset % gridSideEdges;
923
924         mf->v1 = getFaceIndex(ss, f, grid, x+0, y+0, edgeSize, gridSize);
925         mf->v2 = getFaceIndex(ss, f, grid, x+0, y+1, edgeSize, gridSize);
926         mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize);
927         mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize);
928
929         if(faceFlags) {
930                 mf->flag = faceFlags[i*2];
931                 mf->mat_nr = faceFlags[i*2+1];
932         }
933         else mf->flag = ME_SMOOTH;
934 }
935
936 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
937 {
938         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
939         CCGSubSurf *ss = cgdm->ss;
940         DMGridData *vd;
941         int index;
942         int totvert, totedge, totface;
943         int gridSize = ccgSubSurf_getGridSize(ss);
944         int edgeSize = ccgSubSurf_getEdgeSize(ss);
945         int i = 0;
946
947         totface = ccgSubSurf_getNumFaces(ss);
948         for(index = 0; index < totface; index++) {
949                 CCGFace *f = cgdm->faceMap[index].face;
950                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
951
952                 vd= ccgSubSurf_getFaceCenterData(f);
953                 copy_v3_v3(mvert[i].co, vd->co);
954                 normal_float_to_short_v3(mvert[i].no, vd->no);
955                 i++;
956                 
957                 for(S = 0; S < numVerts; S++) {
958                         for(x = 1; x < gridSize - 1; x++, i++) {
959                                 vd= ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
960                                 copy_v3_v3(mvert[i].co, vd->co);
961                                 normal_float_to_short_v3(mvert[i].no, vd->no);
962                         }
963                 }
964
965                 for(S = 0; S < numVerts; S++) {
966                         for(y = 1; y < gridSize - 1; y++) {
967                                 for(x = 1; x < gridSize - 1; x++, i++) {
968                                         vd= ccgSubSurf_getFaceGridData(ss, f, S, x, y);
969                                         copy_v3_v3(mvert[i].co, vd->co);
970                                         normal_float_to_short_v3(mvert[i].no, vd->no);
971                                 }
972                         }
973                 }
974         }
975
976         totedge = ccgSubSurf_getNumEdges(ss);
977         for(index = 0; index < totedge; index++) {
978                 CCGEdge *e = cgdm->edgeMap[index].edge;
979                 int x;
980
981                 for(x = 1; x < edgeSize - 1; x++, i++) {
982                         vd= ccgSubSurf_getEdgeData(ss, e, x);
983                         copy_v3_v3(mvert[i].co, vd->co);
984                         /* This gives errors with -debug-fpe
985                          * the normals dont seem to be unit length.
986                          * this is most likely caused by edges with no
987                          * faces which are now zerod out, see comment in:
988                          * ccgSubSurf__calcVertNormals(), - campbell */
989                         normal_float_to_short_v3(mvert[i].no, vd->no);
990                 }
991         }
992
993         totvert = ccgSubSurf_getNumVerts(ss);
994         for(index = 0; index < totvert; index++) {
995                 CCGVert *v = cgdm->vertMap[index].vert;
996
997                 vd= ccgSubSurf_getVertData(ss, v);
998                 copy_v3_v3(mvert[i].co, vd->co);
999                 normal_float_to_short_v3(mvert[i].no, vd->no);
1000                 i++;
1001         }
1002 }
1003
1004 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
1005 {
1006         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1007         CCGSubSurf *ss = cgdm->ss;
1008         int index;
1009         int totedge, totface;
1010         int gridSize = ccgSubSurf_getGridSize(ss);
1011         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1012         int i = 0;
1013         short *edgeFlags = cgdm->edgeFlags;
1014
1015         totface = ccgSubSurf_getNumFaces(ss);
1016         for(index = 0; index < totface; index++) {
1017                 CCGFace *f = cgdm->faceMap[index].face;
1018                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1019
1020                 for(S = 0; S < numVerts; S++) {
1021                         for(x = 0; x < gridSize - 1; x++) {
1022                                 MEdge *med = &medge[i];
1023
1024                                 if(cgdm->drawInteriorEdges)
1025                                         med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1026                                 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
1027                                 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
1028                                 i++;
1029                         }
1030
1031                         for(x = 1; x < gridSize - 1; x++) {
1032                                 for(y = 0; y < gridSize - 1; y++) {
1033                                         MEdge *med;
1034
1035                                         med = &medge[i];
1036                                         if(cgdm->drawInteriorEdges)
1037                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1038                                         med->v1 = getFaceIndex(ss, f, S, x, y,
1039                                                                                    edgeSize, gridSize);
1040                                         med->v2 = getFaceIndex(ss, f, S, x, y + 1,
1041                                                                                    edgeSize, gridSize);
1042                                         i++;
1043
1044                                         med = &medge[i];
1045                                         if(cgdm->drawInteriorEdges)
1046                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1047                                         med->v1 = getFaceIndex(ss, f, S, y, x,
1048                                                                                    edgeSize, gridSize);
1049                                         med->v2 = getFaceIndex(ss, f, S, y + 1, x,
1050                                                                                    edgeSize, gridSize);
1051                                         i++;
1052                                 }
1053                         }
1054                 }
1055         }
1056
1057         totedge = ccgSubSurf_getNumEdges(ss);
1058         for(index = 0; index < totedge; index++) {
1059                 CCGEdge *e = cgdm->edgeMap[index].edge;
1060                 unsigned int flags = 0;
1061                 int x;
1062                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
1063
1064                 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
1065
1066                 if(edgeFlags) {
1067                         if(edgeIdx != -1) {
1068                                 flags |= (edgeFlags[index] & (ME_SEAM | ME_SHARP))
1069                                                  | ME_EDGEDRAW | ME_EDGERENDER;
1070                         }
1071                 } else {
1072                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
1073                 }
1074
1075                 for(x = 0; x < edgeSize - 1; x++) {
1076                         MEdge *med = &medge[i];
1077                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1078                         med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
1079                         med->flag = flags;
1080                         i++;
1081                 }
1082         }
1083 }
1084
1085 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1086 {
1087         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1088         CCGSubSurf *ss = cgdm->ss;
1089         int index;
1090         int totface;
1091         int gridSize = ccgSubSurf_getGridSize(ss);
1092         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1093         int i = 0;
1094         char *faceFlags = cgdm->faceFlags;
1095
1096         totface = ccgSubSurf_getNumFaces(ss);
1097         for(index = 0; index < totface; index++) {
1098                 CCGFace *f = cgdm->faceMap[index].face;
1099                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1100                 /* keep types in sync with MFace, avoid many conversions */
1101                 char flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
1102                 short mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
1103
1104                 for(S = 0; S < numVerts; S++) {
1105                         for(y = 0; y < gridSize - 1; y++) {
1106                                 for(x = 0; x < gridSize - 1; x++) {
1107                                         MFace *mf = &mface[i];
1108                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1109                                                                                   edgeSize, gridSize);
1110                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1111                                                                                   edgeSize, gridSize);
1112                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1113                                                                                   edgeSize, gridSize);
1114                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1115                                                                                   edgeSize, gridSize);
1116                                         if (faceFlags) {
1117                                                 mat_nr = faceFlags[index*2+1];
1118                                                 mf->flag = faceFlags[index*2];
1119                                         } else mf->flag = flag;
1120
1121                                         mf->mat_nr = mat_nr;
1122                                         mf->flag = flag;
1123
1124                                         i++;
1125                                 }
1126                         }
1127                 }
1128         }
1129 }
1130
1131 static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
1132 {
1133         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1134         CCGSubSurf *ss = cgdm->ss;
1135         int index;
1136         int totface;
1137         int gridSize = ccgSubSurf_getGridSize(ss);
1138         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1139         int i = 0;
1140         MLoop *mv;
1141         /* char *faceFlags = cgdm->faceFlags; */ /* UNUSED */
1142
1143         if (!cgdm->ehash) {
1144                 MEdge *medge;
1145
1146                 cgdm->ehash = BLI_edgehash_new();
1147                 medge = cgdm->dm.getEdgeArray((DerivedMesh*)cgdm);
1148
1149                 for (i=0; i<cgdm->dm.numEdgeData; i++) {
1150                         BLI_edgehash_insert(cgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
1151                 }
1152         }
1153
1154         totface = ccgSubSurf_getNumFaces(ss);
1155         mv = mloop;
1156         for(index = 0; index < totface; index++) {
1157                 CCGFace *f = cgdm->faceMap[index].face;
1158                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1159                 /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */
1160                 /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */
1161
1162                 for(S = 0; S < numVerts; S++) {
1163                         for(y = 0; y < gridSize - 1; y++) {
1164                                 for(x = 0; x < gridSize - 1; x++) {
1165                                         int v1, v2, v3, v4;
1166
1167                                         v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1168                                                                                   edgeSize, gridSize);
1169
1170                                         v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1171                                                                                   edgeSize, gridSize);
1172                                         v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1173                                                                                   edgeSize, gridSize);
1174                                         v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1175                                                                                   edgeSize, gridSize);
1176
1177                                         mv->v = v1;
1178                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v1, v2));
1179                                         mv++, i++;
1180
1181                                         mv->v = v2;
1182                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v2, v3));
1183                                         mv++, i++;
1184
1185                                         mv->v = v3;
1186                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v3, v4));
1187                                         mv++, i++;
1188
1189                                         mv->v = v4;
1190                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v4, v1));
1191                                         mv++, i++;
1192                                 }
1193                         }
1194                 }
1195         }
1196 }
1197
1198
1199 static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mface)
1200 {
1201         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1202         CCGSubSurf *ss = cgdm->ss;
1203         int index;
1204         int totface;
1205         int gridSize = ccgSubSurf_getGridSize(ss);
1206         /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
1207         int i = 0, k = 0;
1208         char *faceFlags = cgdm->faceFlags;
1209
1210         totface = ccgSubSurf_getNumFaces(ss);
1211         for(index = 0; index < totface; index++) {
1212                 CCGFace *f = cgdm->faceMap[index].face;
1213                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1214                 int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
1215                 int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
1216
1217                 for(S = 0; S < numVerts; S++) {
1218                         for(y = 0; y < gridSize - 1; y++) {
1219                                 for(x = 0; x < gridSize - 1; x++) {
1220                                         MPoly *mf = &mface[i];
1221
1222                                         if (faceFlags) {
1223                                                 mat_nr = faceFlags[index*2+1];
1224                                                 mf->flag = faceFlags[index*2];
1225                                         } else mf->flag = flag;
1226
1227                                         mf->mat_nr = mat_nr;
1228                                         mf->flag = flag;
1229                                         mf->loopstart = k;
1230                                         mf->totloop = 4;
1231
1232                                         k += 4;
1233                                         i++;
1234                                 }
1235                         }
1236                 }
1237         }
1238 }
1239
1240 static void cgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
1241         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1242         CCGSubSurf *ss = cgdm->ss;
1243         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1244         int gridSize = ccgSubSurf_getGridSize(ss);
1245         int i;
1246         CCGVertIterator *vi;
1247         CCGEdgeIterator *ei;
1248         CCGFaceIterator *fi;
1249         CCGFace **faceMap2;
1250         CCGEdge **edgeMap2;
1251         CCGVert **vertMap2;
1252         int index, totvert, totedge, totface;
1253         
1254         totvert = ccgSubSurf_getNumVerts(ss);
1255         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1256         vi = ccgSubSurf_getVertIterator(ss);
1257         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1258                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1259
1260                 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1261         }
1262         ccgVertIterator_free(vi);
1263
1264         totedge = ccgSubSurf_getNumEdges(ss);
1265         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1266         ei = ccgSubSurf_getEdgeIterator(ss);
1267         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1268                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1269
1270                 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1271         }
1272
1273         totface = ccgSubSurf_getNumFaces(ss);
1274         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1275         fi = ccgSubSurf_getFaceIterator(ss);
1276         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1277                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1278
1279                 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
1280         }
1281         ccgFaceIterator_free(fi);
1282
1283         i = 0;
1284         for (index=0; index<totface; index++) {
1285                 CCGFace *f = faceMap2[index];
1286                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1287
1288                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
1289                 
1290                 for (S=0; S<numVerts; S++) {
1291                         for (x=1; x<gridSize-1; x++) {
1292                                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1293                         }
1294                 }
1295
1296                 for (S=0; S<numVerts; S++) {
1297                         for (y=1; y<gridSize-1; y++) {
1298                                 for (x=1; x<gridSize-1; x++) {
1299                                         copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1300                                 }
1301                         }
1302                 }
1303         }
1304
1305         for (index=0; index<totedge; index++) {
1306                 CCGEdge *e= edgeMap2[index];
1307                 int x;
1308
1309                 for (x=1; x<edgeSize-1; x++) {
1310                         copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1311                 }
1312         }
1313
1314         for (index=0; index<totvert; index++) {
1315                 CCGVert *v = vertMap2[index];
1316                 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
1317         }
1318
1319         MEM_freeN(vertMap2);
1320         MEM_freeN(edgeMap2);
1321         MEM_freeN(faceMap2);
1322 }
1323 static void cgdm_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1324         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1325         CCGVertIterator *vi = ccgSubSurf_getVertIterator(cgdm->ss);
1326
1327         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1328                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1329                 DMGridData *vd = ccgSubSurf_getVertData(cgdm->ss, v);
1330                 int index = ccgDM_getVertMapIndex(cgdm->ss, v);
1331
1332                 if (index!=-1)
1333                         func(userData, index, vd->co, vd->no, NULL);
1334         }
1335
1336         ccgVertIterator_free(vi);
1337 }
1338 static void cgdm_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1339         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1340         CCGSubSurf *ss = cgdm->ss;
1341         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1342         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1343
1344         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1345                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1346                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1347                 int index = ccgDM_getEdgeMapIndex(ss, e);
1348
1349                 if (index!=-1) {
1350                         for (i=0; i<edgeSize-1; i++)
1351                                 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1352                 }
1353         }
1354
1355         ccgEdgeIterator_free(ei);
1356 }
1357
1358 static void ccgDM_drawVerts(DerivedMesh *dm) {
1359         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1360         CCGSubSurf *ss = cgdm->ss;
1361         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1362         int gridSize = ccgSubSurf_getGridSize(ss);
1363         CCGVertIterator *vi;
1364         CCGEdgeIterator *ei;
1365         CCGFaceIterator *fi;
1366
1367         glBegin(GL_POINTS);
1368         vi = ccgSubSurf_getVertIterator(ss);
1369         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1370                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1371                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1372         }
1373         ccgVertIterator_free(vi);
1374
1375         ei = ccgSubSurf_getEdgeIterator(ss);
1376         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1377                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1378                 int x;
1379
1380                 for (x=1; x<edgeSize-1; x++)
1381                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1382         }
1383         ccgEdgeIterator_free(ei);
1384
1385         fi = ccgSubSurf_getFaceIterator(ss);
1386         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1387                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1388                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1389
1390                 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1391                 for (S=0; S<numVerts; S++)
1392                         for (x=1; x<gridSize-1; x++)
1393                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1394                 for (S=0; S<numVerts; S++)
1395                         for (y=1; y<gridSize-1; y++)
1396                                 for (x=1; x<gridSize-1; x++)
1397                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1398         }
1399         ccgFaceIterator_free(fi);
1400         glEnd();
1401 }
1402
1403 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
1404 {
1405         if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
1406                 CCGFace **faces;
1407                 int totface;
1408
1409                 BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void***)&faces, &totface);
1410                 if(totface) {
1411                         ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
1412                         ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
1413                         MEM_freeN(faces);
1414                 }
1415         }
1416 }
1417
1418 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(drawAllEdges)) {
1419         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1420         CCGSubSurf *ss = ccgdm->ss;
1421         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1422         int totedge = ccgSubSurf_getNumEdges(ss);
1423         int gridSize = ccgSubSurf_getGridSize(ss);
1424         int useAging;
1425
1426         ccgdm_pbvh_update(ccgdm);
1427
1428         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1429
1430         for (j=0; j< totedge; j++) {
1431                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1432                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1433
1434                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1435                         continue;
1436
1437                 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1438                         continue;
1439
1440                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1441                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1442                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1443                 }
1444
1445                 glBegin(GL_LINE_STRIP);
1446                 for (i=0; i<edgeSize-1; i++) {
1447                         glVertex3fv(edgeData[i].co);
1448                         glVertex3fv(edgeData[i+1].co);
1449                 }
1450                 glEnd();
1451         }
1452
1453         if (useAging && !(G.f&G_BACKBUFSEL)) {
1454                 glColor3ub(0, 0, 0);
1455         }
1456
1457         if (ccgdm->drawInteriorEdges) {
1458                 int totface = ccgSubSurf_getNumFaces(ss);
1459
1460                 for(j = 0; j < totface; j++) {
1461                         CCGFace *f = ccgdm->faceMap[j].face;
1462                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1463
1464                         for (S=0; S<numVerts; S++) {
1465                                 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1466
1467                                 glBegin(GL_LINE_STRIP);
1468                                 for (x=0; x<gridSize; x++)
1469                                         glVertex3fv(faceGridData[x].co);
1470                                 glEnd();
1471                                 for (y=1; y<gridSize-1; y++) {
1472                                         glBegin(GL_LINE_STRIP);
1473                                         for (x=0; x<gridSize; x++)
1474                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1475                                         glEnd();
1476                                 }
1477                                 for (x=1; x<gridSize-1; x++) {
1478                                         glBegin(GL_LINE_STRIP);
1479                                         for (y=0; y<gridSize; y++)
1480                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1481                                         glEnd();
1482                                 }
1483                         }
1484                 }
1485         }
1486 }
1487 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1488         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1489         CCGSubSurf *ss = cgdm->ss;
1490         int totedge = ccgSubSurf_getNumEdges(ss);
1491         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1492
1493         for (j=0; j< totedge; j++) {
1494                 CCGEdge *e = cgdm->edgeMap[j].edge;
1495                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1496
1497                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1498                         glBegin(GL_LINE_STRIP);
1499                         for (i=0; i<edgeSize-1; i++) {
1500                                 glVertex3fv(edgeData[i].co);
1501                                 glVertex3fv(edgeData[i+1].co);
1502                         }
1503                         glEnd();
1504                 }
1505         }
1506 }
1507
1508 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1509 {
1510         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1511         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1512         float no[3];
1513
1514         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1515         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1516         no[2] = b_dX*a_cY - b_dY*a_cX;
1517
1518         /* don't normalize, GL_NORMALIZE is enabled */
1519         glNormal3fv(no);
1520 }
1521
1522         /* Only used by non-editmesh types */
1523 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
1524         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1525         CCGSubSurf *ss = ccgdm->ss;
1526         int gridSize = ccgSubSurf_getGridSize(ss);
1527         char *faceFlags = ccgdm->faceFlags;
1528         int step = (fast)? gridSize-1: 1;
1529         int i, totface = ccgSubSurf_getNumFaces(ss);
1530         int drawcurrent = 0, matnr = -1, shademodel = -1;
1531
1532         ccgdm_pbvh_update(ccgdm);
1533
1534         if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1535                 if(dm->numTessFaceData) {
1536                         /* should be per face */
1537                         if(!setMaterial(faceFlags[1]+1, NULL))
1538                                 return;
1539
1540                         glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
1541                         BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH));
1542                         glShadeModel(GL_FLAT);
1543                 }
1544
1545                 return;
1546         }
1547
1548         for(i = 0; i < totface; i++) {
1549                 CCGFace *f = ccgdm->faceMap[i].face;
1550                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1551                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1552                 int new_matnr, new_shademodel;
1553
1554                 if(faceFlags) {
1555                         new_shademodel = (faceFlags[index*2] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT;
1556                         new_matnr= faceFlags[index*2 + 1];
1557                 }
1558                 else {
1559                         new_shademodel = GL_SMOOTH;
1560                         new_matnr= 0;
1561                 }
1562                 
1563                 if(shademodel != new_shademodel || matnr != new_matnr) {
1564                         matnr= new_matnr;
1565                         shademodel= new_shademodel;
1566
1567                         drawcurrent= setMaterial(matnr+1, NULL);
1568
1569                         glShadeModel(shademodel);
1570                 }
1571
1572                 if(!drawcurrent)
1573                         continue;
1574
1575                 for (S=0; S<numVerts; S++) {
1576                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1577
1578                         if (shademodel == GL_SMOOTH) {
1579                                 for (y=0; y<gridSize-1; y+=step) {
1580                                         glBegin(GL_QUAD_STRIP);
1581                                         for (x=0; x<gridSize; x+=step) {
1582                                                 DMGridData *a = &faceGridData[(y+0)*gridSize + x];
1583                                                 DMGridData *b = &faceGridData[(y+step)*gridSize + x];
1584
1585                                                 glNormal3fv(a->no);
1586                                                 glVertex3fv(a->co);
1587                                                 glNormal3fv(b->no);
1588                                                 glVertex3fv(b->co);
1589                                         }
1590                                         glEnd();
1591                                 }
1592                         } else {
1593                                 glBegin(GL_QUADS);
1594                                 for (y=0; y<gridSize-1; y+=step) {
1595                                         for (x=0; x<gridSize-1; x+=step) {
1596                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1597                                                 float *b = faceGridData[(y+0)*gridSize + x + step].co;
1598                                                 float *c = faceGridData[(y+step)*gridSize + x + step].co;
1599                                                 float *d = faceGridData[(y+step)*gridSize + x].co;
1600
1601                                                 ccgDM_glNormalFast(a, b, c, d);
1602
1603                                                 glVertex3fv(d);
1604                                                 glVertex3fv(c);
1605                                                 glVertex3fv(b);
1606                                                 glVertex3fv(a);
1607                                         }
1608                                 }
1609                                 glEnd();
1610                         }
1611                 }
1612         }
1613 }
1614
1615         /* Only used by non-editmesh types */
1616 static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm,
1617                         int (*setMaterial)(int, void *attribs),
1618                         int (*setDrawOptions)(void *userData, int index),
1619                         void *userData)
1620 {
1621         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1622         CCGSubSurf *ss = cgdm->ss;
1623         GPUVertexAttribs gattribs;
1624         DMVertexAttribs attribs= {{{NULL}}};
1625         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1626         int gridSize = ccgSubSurf_getGridSize(ss);
1627         int gridFaces = gridSize - 1;
1628         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1629         char *faceFlags = cgdm->faceFlags;
1630         int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
1631
1632         ccgdm_pbvh_update(cgdm);
1633
1634         doDraw = 0;
1635         matnr = -1;
1636
1637 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1638         if(attribs.totorco) {                                                                                                           \
1639                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1640                 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1641         }                                                                                                                                                       \
1642         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1643                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1644                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
1645         }                                                                                                                                                       \
1646         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1647                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1648                 GLubyte col[4];                                                                                                                 \
1649                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1650                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1651         }                                                                                                                                                       \
1652         if(attribs.tottang) {                                                                                                           \
1653                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1654                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1655         }                                                                                                                                                       \
1656 }
1657
1658         totface = ccgSubSurf_getNumFaces(ss);
1659         for(a = 0, i = 0; i < totface; i++) {
1660                 CCGFace *f = cgdm->faceMap[i].face;
1661                 int S, x, y, drawSmooth;
1662                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1663                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1664                 
1665                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1666
1667                 if(faceFlags) {
1668                         drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1669                         new_matnr= faceFlags[index*2 + 1] + 1;
1670                 }
1671                 else {
1672                         drawSmooth = 1;
1673                         new_matnr= 1;
1674                 }
1675
1676                 if(new_matnr != matnr) {
1677                         doDraw = setMaterial(matnr = new_matnr, &gattribs);
1678                         if(doDraw)
1679                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1680                 }
1681
1682                 if(!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && !setDrawOptions(userData, origIndex))) {
1683                         a += gridFaces*gridFaces*numVerts;
1684                         continue;
1685                 }
1686
1687                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1688                 for (S=0; S<numVerts; S++) {
1689                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1690                         DMGridData *vda, *vdb;
1691
1692                         if (drawSmooth) {
1693                                 for (y=0; y<gridFaces; y++) {
1694                                         glBegin(GL_QUAD_STRIP);
1695                                         for (x=0; x<gridFaces; x++) {
1696                                                 vda = &faceGridData[(y+0)*gridSize + x];
1697                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1698                                                 
1699                                                 PASSATTRIB(0, 0, 0);
1700                                                 glNormal3fv(vda->no);
1701                                                 glVertex3fv(vda->co);
1702
1703                                                 PASSATTRIB(0, 1, 1);
1704                                                 glNormal3fv(vdb->no);
1705                                                 glVertex3fv(vdb->co);
1706
1707                                                 if(x != gridFaces-1)
1708                                                         a++;
1709                                         }
1710
1711                                         vda = &faceGridData[(y+0)*gridSize + x];
1712                                         vdb = &faceGridData[(y+1)*gridSize + x];
1713
1714                                         PASSATTRIB(0, 0, 3);
1715                                         glNormal3fv(vda->no);
1716                                         glVertex3fv(vda->co);
1717
1718                                         PASSATTRIB(0, 1, 2);
1719                                         glNormal3fv(vdb->no);
1720                                         glVertex3fv(vdb->co);
1721
1722                                         glEnd();
1723
1724                                         a++;
1725                                 }
1726                         } else {
1727                                 glBegin(GL_QUADS);
1728                                 for (y=0; y<gridFaces; y++) {
1729                                         for (x=0; x<gridFaces; x++) {
1730                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1731                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1732                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1733                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1734
1735                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1736
1737                                                 PASSATTRIB(0, 1, 1);
1738                                                 glVertex3fv(dco);
1739                                                 PASSATTRIB(1, 1, 2);
1740                                                 glVertex3fv(cco);
1741                                                 PASSATTRIB(1, 0, 3);
1742                                                 glVertex3fv(bco);
1743                                                 PASSATTRIB(0, 0, 0);
1744                                                 glVertex3fv(aco);
1745                                                 
1746                                                 a++;
1747                                         }
1748                                 }
1749                                 glEnd();
1750                         }
1751                 }
1752         }
1753
1754 #undef PASSATTRIB
1755 }
1756
1757 static void cgdm_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1758         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1759 }
1760
1761         /* Only used by non-editmesh types */
1762 static void cgdm_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData) {
1763         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1764         CCGSubSurf *ss = ccgdm->ss;
1765         GPUVertexAttribs gattribs;
1766         DMVertexAttribs attribs= {{{NULL}}};
1767         int gridSize = ccgSubSurf_getGridSize(ss);
1768         int gridFaces = gridSize - 1;
1769         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1770         char *faceFlags = ccgdm->faceFlags;
1771         int a, b, i, numVerts, matnr, new_matnr, totface;
1772
1773         ccgdm_pbvh_update(ccgdm);
1774
1775         matnr = -1;
1776
1777 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1778         if(attribs.totorco) {                                                                                                           \
1779                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1780                 if(attribs.orco.glTexco)                                                                                                \
1781                         glTexCoord3fv(attribs.orco.array[index]);                                                       \
1782                 else                                                                                                                                    \
1783                         glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1784         }                                                                                                                                                       \
1785         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1786                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1787                 if(attribs.tface[b].glTexco)                                                                                    \
1788                         glTexCoord2fv(tf->uv[vert]);                                                                            \
1789                 else                                                                                                                                    \
1790                         glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);           \
1791         }                                                                                                                                                       \
1792         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1793                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1794                 GLubyte col[4];                                                                                                                 \
1795                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1796                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1797         }                                                                                                                                                       \
1798         if(attribs.tottang) {                                                                                                           \
1799                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1800                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1801         }                                                                                                                                                       \
1802 }
1803
1804         totface = ccgSubSurf_getNumFaces(ss);
1805         for(a = 0, i = 0; i < totface; i++) {
1806                 CCGFace *f = ccgdm->faceMap[i].face;
1807                 int S, x, y, drawSmooth;
1808                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1809                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1810                 
1811                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1812
1813                 /* get flags */
1814                 if(faceFlags) {
1815                         drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1816                         new_matnr= faceFlags[index*2 + 1] + 1;
1817                 }
1818                 else {
1819                         drawSmooth = 1;
1820                         new_matnr= 1;
1821                 }
1822
1823                 /* material */
1824                 if(new_matnr != matnr) {
1825                         setMaterial(userData, matnr = new_matnr, &gattribs);
1826                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1827                 }
1828
1829                 /* face hiding */
1830                 if((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) {
1831                         a += gridFaces*gridFaces*numVerts;
1832                         continue;
1833                 }
1834
1835                 /* draw face*/
1836                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1837                 for (S=0; S<numVerts; S++) {
1838                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1839                         DMGridData *vda, *vdb;
1840
1841                         if (drawSmooth) {
1842                                 for (y=0; y<gridFaces; y++) {
1843                                         glBegin(GL_QUAD_STRIP);
1844                                         for (x=0; x<gridFaces; x++) {
1845                                                 vda = &faceGridData[(y+0)*gridSize + x];
1846                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1847                                                 
1848                                                 PASSATTRIB(0, 0, 0);
1849                                                 glNormal3fv(vda->no);
1850                                                 glVertex3fv(vda->co);
1851
1852                                                 PASSATTRIB(0, 1, 1);
1853                                                 glNormal3fv(vdb->no);
1854                                                 glVertex3fv(vdb->co);
1855
1856                                                 if(x != gridFaces-1)
1857                                                         a++;
1858                                         }
1859
1860                                         vda = &faceGridData[(y+0)*gridSize + x];
1861                                         vdb = &faceGridData[(y+1)*gridSize + x];
1862
1863                                         PASSATTRIB(0, 0, 3);
1864                                         glNormal3fv(vda->no);
1865                                         glVertex3fv(vda->co);
1866
1867                                         PASSATTRIB(0, 1, 2);
1868                                         glNormal3fv(vdb->no);
1869                                         glVertex3fv(vdb->co);
1870
1871                                         glEnd();
1872
1873                                         a++;
1874                                 }
1875                         } else {
1876                                 glBegin(GL_QUADS);
1877                                 for (y=0; y<gridFaces; y++) {
1878                                         for (x=0; x<gridFaces; x++) {
1879                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1880                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1881                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1882                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1883
1884                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1885
1886                                                 PASSATTRIB(0, 1, 1);
1887                                                 glVertex3fv(dco);
1888                                                 PASSATTRIB(1, 1, 2);
1889                                                 glVertex3fv(cco);
1890                                                 PASSATTRIB(1, 0, 3);
1891                                                 glVertex3fv(bco);
1892                                                 PASSATTRIB(0, 0, 0);
1893                                                 glVertex3fv(aco);
1894                                                 
1895                                                 a++;
1896                                         }
1897                                 }
1898                                 glEnd();
1899                         }
1900                 }
1901         }
1902
1903 #undef PASSATTRIB
1904 }
1905
1906
1907 static void cgdm_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
1908         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1909         CCGSubSurf *ss = cgdm->ss;
1910         int gridSize = ccgSubSurf_getGridSize(ss);
1911         unsigned char *cp1, *cp2;
1912         int useTwoSide=1, i, totface;
1913
1914         ccgdm_pbvh_update(cgdm);
1915
1916         cp1= col1;
1917         if(col2) {
1918                 cp2= col2;
1919         } else {
1920                 cp2= NULL;
1921                 useTwoSide= 0;
1922         }
1923
1924         glShadeModel(GL_SMOOTH);
1925
1926         if(col2) {
1927                 glEnable(GL_CULL_FACE);
1928         }
1929
1930         glBegin(GL_QUADS);
1931         totface = ccgSubSurf_getNumFaces(ss);
1932         for(i = 0; i < totface; i++) {
1933                 CCGFace *f = cgdm->faceMap[i].face;
1934                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1935
1936                 for (S=0; S<numVerts; S++) {
1937                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1938                         for (y=0; y<gridSize-1; y++) {
1939                                 for (x=0; x<gridSize-1; x++) {
1940                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1941                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1942                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1943                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1944
1945                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1946                                         glVertex3fv(d);
1947                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1948                                         glVertex3fv(c);
1949                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1950                                         glVertex3fv(b);
1951                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1952                                         glVertex3fv(a);
1953
1954                                         if (useTwoSide) {
1955                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1956                                                 glVertex3fv(a);
1957                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1958                                                 glVertex3fv(b);
1959                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1960                                                 glVertex3fv(c);
1961                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1962                                                 glVertex3fv(d);
1963                                         }
1964
1965                                         if (cp2) cp2+=16;
1966                                         cp1+=16;
1967                                 }
1968                         }
1969                 }
1970         }
1971         glEnd();
1972 }
1973
1974 static void cgdm_drawFacesTex_common(DerivedMesh *dm,
1975         int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
1976         int (*drawParamsMapped)(void *userData, int index),
1977         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
1978         void *userData) 
1979 {
1980         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1981         CCGSubSurf *ss = cgdm->ss;
1982         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
1983         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
1984         char *faceFlags = cgdm->faceFlags;
1985         int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1986         int gridFaces = gridSize - 1;
1987
1988         (void) compareDrawOptions;
1989
1990         ccgdm_pbvh_update(cgdm);
1991
1992         if(!mcol)
1993                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
1994
1995         if(!mcol)
1996                 mcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
1997
1998         totface = ccgSubSurf_getNumFaces(ss);
1999         for(i = 0; i < totface; i++) {
2000                 CCGFace *f = cgdm->faceMap[i].face;
2001                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2002                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2003                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2004                 unsigned char *cp= NULL;
2005                 int mat_nr;
2006
2007                 if(faceFlags) {
2008                         drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
2009                         mat_nr= faceFlags[origIndex*2 + 1];
2010                 }
2011                 else {
2012                         drawSmooth = 1;
2013                         mat_nr= 0;
2014                 }
2015
2016                 if(drawParams)
2017                         flag = drawParams(tf, (mcol != NULL), mat_nr);
2018                 else if (index != ORIGINDEX_NONE)
2019                         flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
2020                 else
2021                         flag= GPU_enable_material(mat_nr, NULL) ? 1:0;
2022
2023
2024                 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
2025                         if(tf) tf += gridFaces*gridFaces*numVerts;
2026                         if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
2027                         continue;
2028                 }
2029
2030                 /* flag 1 == use vertex colors */
2031                 if(mcol) {
2032                         if(flag==1) cp= (unsigned char*)mcol;
2033                         mcol += gridFaces*gridFaces*numVerts*4;
2034                 }
2035
2036                 for (S=0; S<numVerts; S++) {
2037                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2038                         DMGridData *a, *b;
2039
2040                         if (drawSmooth) {
2041                                 glShadeModel(GL_SMOOTH);
2042                                 for (y=0; y<gridFaces; y++) {
2043                                         glBegin(GL_QUAD_STRIP);
2044                                         for (x=0; x<gridFaces; x++) {
2045                                                 a = &faceGridData[(y+0)*gridSize + x];
2046                                                 b = &faceGridData[(y+1)*gridSize + x];
2047
2048                                                 if(tf) glTexCoord2fv(tf->uv[0]);
2049                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2050                                                 glNormal3fv(a->no);
2051                                                 glVertex3fv(a->co);
2052
2053                                                 if(tf) glTexCoord2fv(tf->uv[1]);
2054                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2055                                                 glNormal3fv(b->no);
2056                                                 glVertex3fv(b->co);
2057                                                 
2058                                                 if(x != gridFaces-1) {
2059                                                         if(tf) tf++;
2060                                                         if(cp) cp += 16;
2061                                                 }
2062                                         }
2063
2064                                         a = &faceGridData[(y+0)*gridSize + x];
2065                                         b = &faceGridData[(y+1)*gridSize + x];
2066
2067                                         if(tf) glTexCoord2fv(tf->uv[3]);
2068                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2069                                         glNormal3fv(a->no);
2070                                         glVertex3fv(a->co);
2071
2072                                         if(tf) glTexCoord2fv(tf->uv[2]);
2073                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2074                                         glNormal3fv(b->no);
2075                                         glVertex3fv(b->co);
2076
2077                                         if(tf) tf++;
2078                                         if(cp) cp += 16;
2079
2080                                         glEnd();
2081                                 }
2082                         } else {
2083                                 glShadeModel(GL_FLAT);
2084                                 glBegin(GL_QUADS);
2085                                 for (y=0; y<gridFaces; y++) {
2086                                         for (x=0; x<gridFaces; x++) {
2087                                                 float *a_co = faceGridData[(y+0)*gridSize + x].co;
2088                                                 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
2089                                                 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
2090                                                 float *d_co = faceGridData[(y+1)*gridSize + x].co;
2091
2092                                                 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
2093
2094                                                 if(tf) glTexCoord2fv(tf->uv[1]);
2095                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2096                                                 glVertex3fv(d_co);
2097
2098                                                 if(tf) glTexCoord2fv(tf->uv[2]);
2099                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2100                                                 glVertex3fv(c_co);
2101
2102                                                 if(tf) glTexCoord2fv(tf->uv[3]);
2103                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2104                                                 glVertex3fv(b_co);
2105
2106                                                 if(tf) glTexCoord2fv(tf->uv[0]);
2107                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2108                                                 glVertex3fv(a_co);
2109
2110                                                 if(tf) tf++;
2111                                                 if(cp) cp += 16;
2112                                         }
2113                                 }
2114                                 glEnd();
2115                         }
2116                 }
2117         }
2118 }
2119
2120 static void cgdm_drawFacesTex(DerivedMesh *dm,
2121                            int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr),
2122                            int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
2123                            void *userData)
2124 {
2125         cgdm_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
2126 }
2127
2128 static void cgdm_drawMappedFacesTex(DerivedMesh *dm,
2129         int (*setDrawOptions)(void *userData, int index),
2130         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
2131         void *userData)
2132 {
2133         cgdm_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
2134 }
2135
2136 static void cgdm_drawUVEdges(DerivedMesh *dm)
2137 {
2138
2139         MFace *mf = dm->getTessFaceArray(dm);
2140         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
2141         int i;
2142         
2143         if (tf) {
2144                 glBegin(GL_LINES);
2145                 for(i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
2146                         if(!(mf->flag&ME_HIDE)) {
2147                                 glVertex2fv(tf->uv[0]);
2148                                 glVertex2fv(tf->uv[1]);
2149         
2150                                 glVertex2fv(tf->uv[1]);
2151                                 glVertex2fv(tf->uv[2]);
2152         
2153                                 if(!mf->v4) {
2154                                         glVertex2fv(tf->uv[2]);
2155                                         glVertex2fv(tf->uv[0]);
2156                                 } else {
2157                                         glVertex2fv(tf->uv[2]);
2158                                         glVertex2fv(tf->uv[3]);
2159         
2160                                         glVertex2fv(tf->uv[3]);
2161                                         glVertex2fv(tf->uv[0]);
2162                                 }
2163                         }
2164                 }
2165                 glEnd();
2166         }
2167 }
2168
2169 static void ccgDM_drawMappedFaces(DerivedMesh *dm,
2170                         int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
2171                         int (*setMaterial)(int, void *attribs),
2172                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
2173                         void *userData, int useColors)
2174 {
2175         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2176         CCGSubSurf *ss = cgdm->ss;
2177         MCol *mcol= NULL;
2178         int i, gridSize = ccgSubSurf_getGridSize(ss);
2179         char *faceFlags = cgdm->faceFlags;
2180         int gridFaces = gridSize - 1, totface;
2181
2182         /* currently unused -- each original face is handled separately */
2183         (void)compareDrawOptions;
2184
2185         if(useColors) {
2186                 mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
2187                 if(!mcol)
2188                         mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
2189         }
2190
2191         totface = ccgSubSurf_getNumFaces(ss);
2192         for(i = 0; i < totface; i++) {
2193                 CCGFace *f = cgdm->faceMap[i].face;
2194                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2195                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2196                 int origIndex;
2197                 unsigned char *cp= NULL;
2198
2199                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2200
2201                 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
2202                 else drawSmooth = 1;
2203
2204                 if(mcol) {
2205                         cp= (unsigned char*)mcol;
2206                         mcol += gridFaces*gridFaces*numVerts*4;
2207                 }
2208
2209                 {
2210                         int draw= 1;
2211
2212                         if(index == ORIGINDEX_NONE)
2213                                 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */
2214                         else if (setDrawOptions)
2215                                 draw= setDrawOptions(userData, index, &drawSmooth);
2216
2217                         if (draw) {
2218                                 if (draw==2) {
2219                                           glEnable(GL_POLYGON_STIPPLE);
2220                                           glPolygonStipple(stipple_quarttone);
2221                                 }
2222
2223                                 /* no need to set shading mode to flat because
2224                                 *  normals are already used to change shading */
2225                                 glShadeModel(GL_SMOOTH);
2226                                 
2227                                 for (S=0; S<numVerts; S++) {
2228                                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2229                                         if (drawSmooth) {
2230                                                 for (y=0; y<gridFaces; y++) {
2231                                                         DMGridData *a, *b;
2232                                                         glBegin(GL_QUAD_STRIP);
2233                                                         for (x=0; x<gridFaces; x++) {
2234                                                                 a = &faceGridData[(y+0)*gridSize + x];
2235                                                                 b = &faceGridData[(y+1)*gridSize + x];
2236         
2237                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2238                                                                 glNormal3fv(a->no);
2239                                                                 glVertex3fv(a->co);
2240                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2241                                                                 glNormal3fv(b->no);
2242                                                                 glVertex3fv(b->co);
2243
2244                                                                 if(x != gridFaces-1) {
2245                                                                         if(cp) cp += 16;
2246                                                                 }
2247                                                         }
2248
2249                                                         a = &faceGridData[(y+0)*gridSize + x];
2250                                                         b = &faceGridData[(y+1)*gridSize + x];
2251
2252                                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2253                                                         glNormal3fv(a->no);
2254                                                         glVertex3fv(a->co);
2255                                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2256                                                         glNormal3fv(b->no);
2257                                                         glVertex3fv(b->co);
2258
2259                                                         if(cp) cp += 16;
2260
2261                                                         glEnd();
2262                                                 }
2263                                         } else {
2264                                                 glBegin(GL_QUADS);
2265                                                 for (y=0; y<gridFaces; y++) {
2266                                                         for (x=0; x<gridFaces; x++) {
2267                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2268                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2269                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2270                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2271
2272                                                                 ccgDM_glNormalFast(a, b, c, d);
2273         
2274                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2275                                                                 glVertex3fv(d);
2276                                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2277                                                                 glVertex3fv(c);
2278                                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2279                                                                 glVertex3fv(b);
2280                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2281                                                                 glVertex3fv(a);
2282
2283                                                                 if(cp) cp += 16;
2284                                                         }
2285                                                 }
2286                                                 glEnd();
2287                                         }
2288                                 }
2289                                 if (draw==2)
2290                                         glDisable(GL_POLYGON_STIPPLE);
2291                         }
2292                 }
2293         }
2294 }
2295 static void cgdm_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2296         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2297         CCGSubSurf *ss = cgdm->ss;
2298         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2299         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2300
2301         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2302
2303         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2304                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2305                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2306                 int index = ccgDM_getEdgeMapIndex(ss, e);
2307
2308                 glBegin(GL_LINE_STRIP);
2309                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2310                         if (useAging && !(G.f&G_BACKBUFSEL)) {
2311                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2312                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
2313                         }
2314
2315                         for (i=0; i<edgeSize-1; i++) {
2316                                 glVertex3fv(edgeData[i].co);
2317                                 glVertex3fv(edgeData[i+1].co);
2318                         }
2319                 }
2320                 glEnd();
2321         }
2322
2323         ccgEdgeIterator_free(ei);
2324 }
2325 static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2326         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2327         CCGSubSurf *ss = cgdm->ss;
2328         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2329         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2330
2331         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2332
2333         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2334                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2335                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2336                 int index = ccgDM_getEdgeMapIndex(ss, e);
2337
2338                 glBegin(GL_LINE_STRIP);
2339                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2340                         for (i=0; i<edgeSize; i++) {
2341                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2342
2343                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
2344                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2345                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
2346                                 }
2347
2348                                 glVertex3fv(edgeData[i].co);
2349                         }
2350                 }
2351                 glEnd();
2352         }
2353
2354         ccgEdgeIterator_free(ei);
2355 }
2356 static void cgdm_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2357         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2358         CCGSubSurf *ss = cgdm->ss;
2359         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2360
2361         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2362                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2363                 int index = ccgDM_getFaceMapIndex(ss, f);
2364
2365                 if (index!=-1) {
2366                                 /* Face center data normal isn't updated atm. */
2367                         DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2368
2369                         func(userData, index, vd->co, vd->no);
2370                 }
2371         }
2372
2373         ccgFaceIterator_free(fi);
2374 }
2375
2376 static void cgdm_release(DerivedMesh *dm) {
2377         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2378
2379         if (DM_release(dm)) {
2380                 /* Before freeing, need to update the displacement map */
2381                 if(ccgdm->multires.modified) {
2382                         /* Check that mmd still exists */
2383                         if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2384                                 ccgdm->multires.mmd = NULL;
2385                         if(ccgdm->multires.mmd)
2386                                 ccgdm->multires.update(dm);
2387                 }
2388
2389                 if (ccgdm->ehash)
2390                         BLI_edgehash_free(ccgdm->ehash, NULL);
2391
2392                 if(ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);
2393                 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
2394                 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
2395                 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
2396                 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2397                 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2398                 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2399                 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2400                 MEM_freeN(ccgdm->edgeFlags);
2401                 MEM_freeN(ccgdm->faceFlags);
2402                 MEM_freeN(ccgdm->vertMap);
2403                 MEM_freeN(ccgdm->edgeMap);
2404                 MEM_freeN(ccgdm->faceMap);
2405                 MEM_freeN(ccgdm);
2406         }
2407 }
2408
2409 static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, 
2410                           CustomData *pdata, int loopstart, int findex, 
2411                           int polyindex, int numTex, int numCol) 
2412 {
2413         MTFace *texface;
2414         MTexPoly *texpoly;
2415         MCol *mcol;
2416         MLoopCol *mloopcol;
2417         MLoopUV *mloopuv;
2418         int i, j, hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
2419
2420         for(i=0; i < numTex; i++){
2421                 texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
2422                 texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
2423                 
2424                 texface->tpage = texpoly->tpage;
2425                 texface->flag = texpoly->flag;
2426                 texface->transp = texpoly->transp;
2427                 texface->mode = texpoly->mode;
2428                 texface->tile = texpoly->tile;
2429                 texface->unwrap = texpoly->unwrap;
2430
2431                 mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
2432                 for (j=0; j<4; j++, mloopuv++) {
2433                         texface->uv[j][0] = mloopuv->uv[0];
2434                         texface->uv[j][1] = mloopuv->uv[1];
2435                 }
2436         }
2437
2438         for(i=0; i < numCol; i++){
2439                 mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i);
2440                 mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
2441
2442                 for (j=0; j<4; j++, mloopcol++) {
2443                         mcol[j].r = mloopcol->r;
2444                         mcol[j].g = mloopcol->g;
2445                         mcol[j].b = mloopcol->b;
2446                         mcol[j].a = mloopcol->a;
2447                 }
2448         }
2449         
2450         if (hasWCol) {
2451                 mloopcol = CustomData_get(ldata, loopstart, CD_WEIGHT_MLOOPCOL);
2452                 mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
2453
2454                 for (j=0; j<4; j++, mloopcol++) {
2455                         mcol[j].r = mloopcol->r;
2456                         mcol[j].g = mloopcol->g;
2457                         mcol[j].b = mloopcol->b;
2458                         mcol[j].a = mloopcol->a;
2459                 }
2460         }
2461 }
2462
2463 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2464 {
2465         if(type == CD_ORIGINDEX) {
2466                 /* create origindex on demand to save memory */
2467                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2468                 CCGSubSurf *ss= cgdm->ss;
2469                 int *origindex;
2470                 int a, index, totnone, totorig;
2471
2472                 /* Avoid re-creation if the layer exists already */
2473                 origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2474                 if (origindex) {
2475                         return origindex;
2476                 }
2477
2478                 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2479                 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2480
2481                 totorig = ccgSubSurf_getNumVerts(ss);
2482                 totnone= dm->numVertData - totorig;
2483
2484                 /* original vertices are at the end */
2485                 for(a=0; a<totnone; a++)
2486                         origindex[a]= ORIGINDEX_NONE;
2487
2488                 for(index=0; index<totorig; index++, a++) {
2489                         CCGVert *v = cgdm->vertMap[index].vert;
2490                         origindex[a] = ccgDM_getVertMapIndex(cgdm->ss, v);
2491                 }
2492
2493                 return origindex;
2494         }
2495
2496         return DM_get_vert_data_layer(dm, type);
2497 }
2498
2499 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2500 {
2501         if(type == CD_ORIGINDEX) {
2502                 /* create origindex on demand to save memory */
2503                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2504                 CCGSubSurf *ss= cgdm->ss;
2505                 int *origindex;
2506                 int a, i, index, totnone, totorig, totedge;
2507                 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2508
2509                 /* Avoid re-creation if the layer exists already */
2510                 origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2511                 if (origindex) {
2512                         return origindex;
2513                 }
2514
2515                 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2516                 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2517
2518                 totedge= ccgSubSurf_getNumEdges(ss);
2519                 totorig= totedge*(edgeSize - 1);
2520                 totnone= dm->numEdgeData - totorig;
2521
2522                 /* original edges are at the end */
2523                 for(a=0; a<totnone; a++)
2524                         origindex[a]= ORIGINDEX_NONE;
2525
2526                 for(index=0; index<totedge; index++) {
2527                         CCGEdge *e= cgdm->edgeMap[index].edge;
2528                         int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2529
2530                         for(i = 0; i < edgeSize - 1; i++, a++)
2531                                 origindex[a]= mapIndex;
2532                 }
2533
2534                 return origindex;
2535         }
2536
2537         return DM_get_edge_data_layer(dm, type);
2538 }
2539
2540 static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type)
2541 {
2542         if(type == CD_ORIGINDEX) {
2543                 /* create origindex on demand to save memory */
2544                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2545                 CCGSubSurf *ss= cgdm->ss;
2546                 int *origindex;
2547                 int a, i, index, totface;
2548                 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2549
2550                 /* Avoid re-creation if the layer exists already */
2551                 origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
2552                 if (origindex) {
2553                         return origindex;
2554                 }
2555
2556                 DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2557                 origindex= DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
2558
2559                 totface= ccgSubSurf_getNumFaces(ss);
2560
2561                 for(a=0, index=0; index<totface; index++) {
2562                         CCGFace *f = cgdm->faceMap[index].face;
2563                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2564                         int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2565
2566                         for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2567                                 origindex[a]= mapIndex;
2568                 }
2569
2570                 return origindex;
2571         }
2572
2573         return DM_get_tessface_data_layer(dm, type);
2574 }
2575
2576 static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type)
2577 {
2578         if (type == CD_ORIGINDEX) {
2579                 /* ensure creation of CD_ORIGINDEX layer */
2580                 ccgDM_get_vert_data_layer(dm, type);
2581         }
2582
2583         return DM_get_vert_data(dm, index, type);
2584 }
2585
2586 static void *ccgDM_get_edge_data(DerivedMesh *dm, int index, int type)
2587 {
2588         if (type == CD_ORIGINDEX) {
2589                 /* ensure creation of CD_ORIGINDEX layer */
2590                 ccgDM_get_edge_data_layer(dm, type);
2591         }
2592
2593         return DM_get_edge_data(dm, index, type);
2594 }
2595
2596 static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type)
2597 {
2598         if (type == CD_ORIGINDEX) {
2599                 /* ensure creation of CD_ORIGINDEX layer */
2600                 ccgDM_get_tessface_data_layer(dm, type);
2601         }
2602
2603         return DM_get_tessface_data(dm, index, type);
2604 }
2605
2606 static int ccgDM_getNumGrids(DerivedMesh *dm)
2607 {
2608         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2609         int index, numFaces, numGrids;
2610
2611         numFaces= ccgSubSurf_getNumFaces(cgdm->ss);
2612         numGrids= 0;
2613
2614         for(index=0; index<numFaces; index++) {
2615                 CCGFace *f = cgdm->faceMap[index].face;
2616                 numGrids += ccgSubSurf_getFaceNumVerts(f);
2617         }
2618
2619         return numGrids;
2620 }
2621
2622 static int ccgDM_getGridSize(DerivedMesh *dm)
2623 {
2624         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2625         return ccgSubSurf_getGridSize(cgdm->ss);
2626 }
2627
2628 static int cgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2629 {
2630         CCGFace *adjf;
2631         CCGEdge *e;
2632         int i, j= 0, numFaces, fIndex, numEdges= 0;
2633
2634         e = ccgSubSurf_getFaceEdge(ss, f, S);
2635         numFaces = ccgSubSurf_getEdgeNumFaces(e);
2636
2637         if(numFaces != 2)
2638                 return -1;
2639
2640         for(i = 0; i < numFaces; i++) {
2641                 adjf = ccgSubSurf_getEdgeFace(e, i);
2642
2643                 if(adjf != f) {
2644                         numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2645                         for(j = 0; j < numEdges; j++)
2646                                 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2647                                         break;
2648
2649                         if(j != numEdges)
2650                                 break;
2651                 }
2652         }
2653         
2654         fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2655
2656         return gridOffset[fIndex] + (j + offset)%numEdges;
2657 }
2658
2659 static void ccgdm_create_grids(DerivedMesh *dm)
2660 {
2661         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2662         CCGSubSurf *ss= cgdm->ss;
2663         DMGridData **gridData;
2664         DMGridAdjacency *gridAdjacency, *adj;
2665         CCGFace **gridFaces;
2666         int *gridOffset;
2667         int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2668
2669         if(cgdm->gridData)
2670                 return;
2671         
2672         numGrids = ccgDM_getNumGrids(dm);
2673         numFaces = ccgSubSurf_getNumFaces(ss);
2674         /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
2675
2676         /* compute offset into grid array for each face */
2677         gridOffset = MEM_mallocN(sizeof(int)*numFaces, "cgdm.gridOffset");
2678
2679         for(gIndex = 0, index = 0; index < numFaces; index++) {
2680                 CCGFace *f = cgdm->faceMap[index].face;
2681                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2682
2683                 gridOffset[index] = gIndex;
2684                 gIndex += numVerts;
2685         }
2686
2687         /* compute grid data */
2688         gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "cgdm.gridData");
2689         gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "cgdm.gridAdjacency");
2690         gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "cgdm.gridFaces");
2691
2692         for(gIndex = 0, index = 0; index < numFaces; index++) {
2693                 CCGFace *f = cgdm->faceMap[index].face;
2694                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2695
2696                 for(S = 0; S < numVerts; S++, gIndex++) {
2697                         int prevS = (S - 1 + numVerts) % numVerts;
2698                         int nextS = (S + 1 + numVerts) % numVerts;
2699
2700                         gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2701                         gridFaces[gIndex] = f;
2702
2703                         adj = &gridAdjacency[gIndex];
2704
2705                         adj->index[0] = gIndex - S + nextS;
2706                         adj->rotation[0] = 3;
2707                         adj->index[1] = cgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2708                         adj->rotation[1] = 1;
2709                         adj->index[2] = cgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2710                         adj->rotation[2] = 3;
2711                         adj->index[3] = gIndex - S + prevS;
2712                         adj->rotation[3] = 1;
2713                 }
2714         }
2715
2716         cgdm->gridData = gridData;
2717         cgdm->gridFaces = gridFaces;
2718         cgdm->gridAdjacency = gridAdjacency;
2719         cgdm->gridOffset = gridOffset;
2720 }
2721
2722 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2723 {
2724         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2725
2726         ccgdm_create_grids(dm);
2727         return cgdm->gridData;
2728 }
2729
2730 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2731 {
2732         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2733
2734         ccgdm_create_grids(dm);
2735         return cgdm->gridAdjacency;
2736 }
2737
2738 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2739 {
2740         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2741
2742         ccgdm_create_grids(dm);
2743         return cgdm->gridOffset;
2744 }
2745
2746 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2747 {
2748         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2749
2750         if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2751                 Mesh *me= ob->data;
2752
2753                 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2754                                      me->totvert, me->totface);
2755         }
2756
2757         return ccgdm->fmap;
2758 }
2759
2760 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2761 {
2762         MultiresModifierData *mmd= ccgdm->multires.mmd;
2763
2764         /* both of multires and subsurm modifiers are CCG, but
2765            grids should only be used when sculpting on multires */
2766         if(!mmd)
2767                 return 0;
2768
2769         return 1;
2770 }
2771
2772 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2773 {
2774         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2775         int gridSize, numGrids, grid_pbvh;
2776
2777         if(!ob) {
2778                 ccgdm->pbvh= NULL;
2779                 return NULL;
2780         }
2781
2782         if(!ob->sculpt)
2783                 return NULL;
2784
2785         grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2786
2787         if(ob->sculpt->pbvh) {
2788                 if(grid_pbvh) {
2789                         /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2790                            but this can be freed on ccgdm release, this updates the pointers
2791                            when the ccgdm gets remade, the assumption is that the topology
2792                            does not change. */
2793                         ccgdm_create_grids(dm);
2794                         BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2795                 }
2796
2797                 ccgdm->pbvh = ob->sculpt->pbvh;
2798         }
2799
2800         if(ccgdm->pbvh)
2801                 return ccgdm->pbvh;
2802
2803         /* no pbvh exists yet, we need to create one. only in case of multires
2804            we build a pbvh over the modified mesh, in other cases the base mesh
2805            is being sculpted, so we build a pbvh from that. */
2806         if(grid_pbvh) {
2807                 ccgdm_create_grids(dm);
2808
2809                 gridSize = ccgDM_getGridSize(dm);
2810                 numGrids = ccgDM_getNumGrids(dm);
2811
2812                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2813                 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2814                         numGrids, gridSize, (void**)ccgdm->gridFaces);
2815         } else if(ob->type == OB_MESH) {
2816                 Mesh *me= ob->data;
2817                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2818                 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2819                                    me->totface, me->totvert);
2820         }
2821
2822         return ccgdm->pbvh;
2823 }
2824
2825 static void ccgDM_recalcTesselection(DerivedMesh *UNUSED(dm))
2826 {
2827         /* Nothing to do: CCG handles creating its own tessfaces */
2828 }
2829
2830 static void ccgDM_calcNormals(DerivedMesh *UNUSED(dm))
2831 {
2832         /* Nothing to do: CCG calculates normals during drawing */
2833 }
2834
2835 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,