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