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