EditMode armature: mirrored editing feature.
[blender.git] / source / blender / blenkernel / intern / subsurf_ccg.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2005 Blender Foundation.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
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
46 #include "BKE_bad_level_calls.h"
47 #include "BKE_utildefines.h"
48 #include "BKE_global.h"
49 #include "BKE_mesh.h"
50 #include "BKE_subsurf.h"
51 #include "BKE_displist.h"
52 #include "BKE_DerivedMesh.h"
53
54 #include "BLI_blenlib.h"
55 #include "BLI_editVert.h"
56 #include "BLI_arithb.h"
57 #include "BLI_linklist.h"
58 #include "BLI_memarena.h"
59
60 #include "BIF_gl.h"
61
62 #include "CCGSubSurf.h"
63
64 typedef struct _VertData {
65         float co[3];
66         float no[3];
67 } VertData;
68
69 typedef struct CCGDerivedMesh CCGDerivedMesh;
70
71 static EditVert *ccgDM_getVertHandle(CCGDerivedMesh *ccgdm, CCGVert *v);
72 static EditEdge *ccgDM_getEdgeHandle(CCGDerivedMesh *ccgdm, CCGEdge *e);
73 static EditFace *ccgDM_getFaceHandle(CCGDerivedMesh *ccgdm, CCGFace *f);
74
75 ///
76
77 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
78         return BLI_memarena_alloc(a, numBytes);
79 }
80 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
81         void *p2 = BLI_memarena_alloc(a, newSize);
82         if (ptr) {
83                 memcpy(p2, ptr, oldSize);
84         }
85         return p2;
86 }
87 static void arena_free(CCGAllocatorHDL a, void *ptr) {
88 }
89 static void arena_release(CCGAllocatorHDL a) {
90         BLI_memarena_free(a);
91 }
92
93 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useEdgeCreation, int useFlatSubdiv) {
94         CCGMeshIFC ifc;
95         CCGSubSurf *ccgSS;
96
97                 /* subdivLevels==0 is not allowed */
98         subdivLevels = MAX2(subdivLevels, 1);
99
100         if (prevSS) {
101                 int oldUseAging;
102
103                 useAging = !!useAging;
104                 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
105
106                 if (oldUseAging!=useAging) {
107                         ccgSubSurf_free(prevSS);
108                 } else {
109                         ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
110
111                         return prevSS;
112                 }
113         }
114
115         if (useAging) {
116                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
117         } else {
118                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 4;
119         }
120         ifc.vertDataSize = sizeof(VertData);
121
122         if (useArena) {
123                 CCGAllocatorIFC allocatorIFC;
124                 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16));
125
126                 allocatorIFC.alloc = arena_alloc;
127                 allocatorIFC.realloc = arena_realloc;
128                 allocatorIFC.free = arena_free;
129                 allocatorIFC.release = arena_release;
130
131                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
132         } else {
133                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
134         }
135
136         if (useAging) {
137                 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 4, 4, 4);
138         }
139         if (useEdgeCreation) {
140                 ccgSubSurf_setAllowEdgeCreation(ccgSS, 1, useFlatSubdiv?subdivLevels:0.0f);
141         }
142
143         ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
144
145         return ccgSS;
146 }
147
148 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
149         CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e);
150         CCGVert *v1 = ccgSubSurf_getEdgeVert1(ss, e);
151         int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
152         int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
153         int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
154
155         if (x==0) {
156                 return v0idx;
157         } else if (x==edgeSize-1) {
158                 return v1idx;
159         } else {
160                 return edgeBase + x-1;
161         }
162 }
163 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
164         int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
165         int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
166
167         if (x==gridSize-1 && y==gridSize-1) {
168                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
169                 return *((int*) ccgSubSurf_getVertUserData(ss, v));
170         } else if (x==gridSize-1) {
171                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
172                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
173                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
174                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
175                         return edgeBase + (gridSize-1-y)-1;
176                 } else {
177                         return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
178                 }
179         } else if (y==gridSize-1) {
180                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
181                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
182                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
183                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
184                         return edgeBase + (gridSize-1-x)-1;
185                 } else {
186                         return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
187                 }
188         } else if (x==0 && y==0) {
189                 return faceBase;
190         } else if (x==0) {
191                 S = (S+numVerts-1)%numVerts;
192                 return faceBase + 1 + (gridSize-2)*S + (y-1);
193         } else if (y==0) {
194                 return faceBase + 1 + (gridSize-2)*S + (x-1);
195         } else {
196                 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
197         }
198 }
199 static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, int drawInteriorEdges, Mesh *inMe, DispListMesh *inDLM, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) {
200         DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
201         int edgeSize = ccgSubSurf_getEdgeSize(ss);
202         int gridSize = ccgSubSurf_getGridSize(ss);
203         int edgeIndexBase, edgeBase, faceIndexBase, faceBase;
204         int i, j, k, S, x, y;
205         int vertBase = 0;
206         TFace *tface = NULL;
207         MEdge *medge = NULL;
208         MFace *mface = NULL;
209         MCol *mcol = NULL;
210         CCGVertIterator *vi;
211         CCGEdgeIterator *ei;
212         CCGFaceIterator *fi;
213         EditVert **vertMap = NULL;
214         EditEdge **edgeMap = NULL;
215         EditFace **faceMap = NULL;
216
217         if (!ssFromEditmesh) {
218                 if (inDLM) {
219                         tface = inDLM->tface;
220                         medge = inDLM->medge;
221                         mface = inDLM->mface;
222                         mcol = inDLM->mcol;
223                 } else if (inMe) {
224                         tface = inMe->tface;
225                         medge = inMe->medge;
226                         mface = inMe->mface;
227                         mcol = inMe->mcol;
228                 }
229         }
230
231         dlm->totvert = ccgSubSurf_getNumFinalVerts(ss);
232         dlm->totedge = ccgSubSurf_getNumFinalEdges(ss);
233         dlm->totface = ccgSubSurf_getNumFinalFaces(ss);
234
235         if (vertMap_r) {
236                 *vertMap_r = vertMap = MEM_callocN(dlm->totvert*sizeof(*vertMap), "vmap");
237                 *edgeMap_r = edgeMap = MEM_callocN(dlm->totedge*sizeof(*edgeMap), "emap");
238                 *faceMap_r = faceMap = MEM_callocN(dlm->totface*sizeof(*faceMap), "fmap");
239         }
240
241         dlm->mvert = MEM_callocN(dlm->totvert*sizeof(*dlm->mvert), "dlm->mvert");
242         dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge");
243         dlm->mface = MEM_callocN(dlm->totface*sizeof(*dlm->mface), "dlm->mface");
244         if (!ssFromEditmesh && tface) {
245                 dlm->tface = MEM_callocN(dlm->totface*sizeof(*dlm->tface), "dlm->tface");
246                 dlm->mcol = NULL;
247         } else if (!ssFromEditmesh && mcol) {
248                 dlm->tface = NULL;
249                 dlm->mcol = MEM_mallocN(dlm->totface*4*sizeof(*dlm->mcol), "dlm->mcol");
250         } else {
251                 dlm->tface = NULL;
252                 dlm->mcol = NULL;
253         }
254
255                 // load vertices
256
257         vertBase = i = 0;
258         vi = ccgSubSurf_getVertIterator(ss);
259         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
260                 CCGVert *v = ccgVertIterator_getCurrent(vi);
261                 VecCopyf(dlm->mvert[i].co, ccgSubSurf_getVertData(ss, v));
262                 if (vertMap) {
263                         vertMap[i] = ccgDM_getVertHandle(ccgdm, v);
264                 }
265                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = i++;
266         }
267         ccgVertIterator_free(vi);
268
269         edgeIndexBase = edgeBase = i;
270         ei = ccgSubSurf_getEdgeIterator(ss);
271         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
272                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
273                 int x;
274
275                 for (x=1; x<edgeSize-1; x++) {
276                         VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
277                 }
278
279                 *((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
280                 edgeBase += edgeSize-2;
281         }
282         ccgEdgeIterator_free(ei);
283
284         faceIndexBase = faceBase = i;
285         fi = ccgSubSurf_getFaceIterator(ss);
286         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
287                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
288                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
289
290                 VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceCenterData(ss, f));
291                 
292                 for (S=0; S<numVerts; S++) {
293                         for (x=1; x<gridSize-1; x++) {
294                                 VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
295                         }
296                 }
297
298                 for (S=0; S<numVerts; S++) {
299                         for (y=1; y<gridSize-1; y++) {
300                                 for (x=1; x<gridSize-1; x++) {
301                                         VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceGridData(ss, f, S, x, y));
302                                 }
303                         }
304                 }
305
306                 *((int*) ccgSubSurf_getFaceUserData(ss, f)) = faceBase;
307                 faceBase += 1 + numVerts*((gridSize-2) + (gridSize-2)*(gridSize-2));
308         }
309         ccgFaceIterator_free(fi);
310
311                 // load edges
312
313         i=0;
314         ei = ccgSubSurf_getEdgeIterator(ss);
315         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
316                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
317                 for (x=0; x<edgeSize-1; x++) {
318                         MEdge *med = &dlm->medge[i];
319                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
320                         med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
321                         med->flag = ME_EDGEDRAW|ME_EDGERENDER;
322
323                         if (!ccgSubSurf_getEdgeNumFaces(ss, e)) med->flag |= ME_LOOSEEDGE;
324
325                         if (ssFromEditmesh) {
326                                 EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e);
327
328                                 if (eed->seam) {
329                                         med->flag|= ME_SEAM;
330                                 }
331                         } else {
332                                 int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e);
333
334                                         /* Edges created by lib have handle of -1 */
335                                 if (edgeIdx!=-1 && medge) {
336                                         MEdge *origMed = &medge[edgeIdx];
337
338                                         med->flag|= (origMed->flag&ME_SEAM);
339                                 }
340                         }
341
342                         if (edgeMap) {
343                                 edgeMap[i] = ccgDM_getEdgeHandle(ccgdm, e);
344                         }
345
346                         i++;
347                 }
348         }
349         ccgEdgeIterator_free(ei);
350
351         fi = ccgSubSurf_getFaceIterator(ss);
352         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
353                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
354                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
355
356                 for (k=0; k<numVerts; k++) {
357                         for (x=0; x<gridSize-1; x++) {
358                                 MEdge *med = &dlm->medge[i];
359                                 if (drawInteriorEdges) med->flag = ME_EDGEDRAW|ME_EDGERENDER;
360                                 med->v1 = getFaceIndex(ss, f, k, x, 0, edgeSize, gridSize);
361                                 med->v2 = getFaceIndex(ss, f, k, x+1, 0, edgeSize, gridSize);
362                                 i++;
363                         }
364
365                         for (x=1; x<gridSize-1; x++) {
366                                 for (y=0; y<gridSize-1; y++) {
367                                         MEdge *med;
368                                         
369                                         med = &dlm->medge[i];
370                                         if (drawInteriorEdges) med->flag = ME_EDGEDRAW|ME_EDGERENDER;
371                                         med->v1 = getFaceIndex(ss, f, k, x, y, edgeSize, gridSize);
372                                         med->v2 = getFaceIndex(ss, f, k, x, y+1, edgeSize, gridSize);
373                                         i++;
374
375                                         med = &dlm->medge[i];
376                                         if (drawInteriorEdges) med->flag = ME_EDGEDRAW|ME_EDGERENDER;
377                                         med->v1 = getFaceIndex(ss, f, k, y, x, edgeSize, gridSize);
378                                         med->v2 = getFaceIndex(ss, f, k, y+1, x, edgeSize, gridSize);
379                                         i++;
380                                 }
381                         }
382                 }
383         }
384         ccgFaceIterator_free(fi);
385
386                 // load faces
387
388         i = 0;
389         fi = ccgSubSurf_getFaceIterator(ss);
390         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
391                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
392                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
393                 float edge_data[4][6];
394                 float corner_data[4][6];
395                 float center_data[6] = {0};
396                 int numDataComponents = 0;
397                 TFace *origTFace = NULL;
398                 int mat_nr;
399                 int flag;
400
401                 if (!ssFromEditmesh) {
402                         int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
403                         MFace *origMFace = &mface[origIdx];
404                         
405                         if (tface) {
406                                 origTFace = &tface[origIdx];
407
408                                 for (S=0; S<numVerts; S++) {
409                                         unsigned char *col = (unsigned char*) &origTFace->col[S];
410                                         corner_data[S][0] = col[0]/255.0f;
411                                         corner_data[S][1] = col[1]/255.0f;
412                                         corner_data[S][2] = col[2]/255.0f;
413                                         corner_data[S][3] = col[3]/255.0f;
414                                         corner_data[S][4] = origTFace->uv[S][0];
415                                         corner_data[S][5] = origTFace->uv[S][1];
416                                 }
417                                 numDataComponents = 6;
418                         } else if (mcol) {
419                                 MCol *origMCol = &mcol[origIdx*4];
420
421                                 for (S=0; S<numVerts; S++) {
422                                         unsigned char *col = (unsigned char*) &origMCol[S];
423                                         corner_data[S][0] = col[0]/255.0f;
424                                         corner_data[S][1] = col[1]/255.0f;
425                                         corner_data[S][2] = col[2]/255.0f;
426                                         corner_data[S][3] = col[3]/255.0f;
427                                 }
428                                 numDataComponents = 4;
429                         }
430
431                         mat_nr = origMFace->mat_nr;
432                         flag = origMFace->flag;
433                 } else {
434                         EditFace *ef = ccgSubSurf_getFaceFaceHandle(ss, f);
435                         mat_nr = ef->mat_nr;
436                         flag = ef->flag;
437                 }
438
439                 for (S=0; S<numVerts; S++) {
440                         for (k=0; k<numDataComponents; k++) {
441                                 edge_data[S][k] = (corner_data[S][k] + corner_data[(S+1)%numVerts][k])*0.5f;
442                                 center_data[k]+= corner_data[S][k];
443                         }
444                 }
445                 for (k=0; k<numDataComponents; k++) {
446                         center_data[k]/= numVerts;
447                 }
448
449                 for (S=0; S<numVerts; S++) {
450                         int prevS= (S-1+numVerts)%numVerts;
451
452                         for (y=0; y<gridSize-1; y++) {
453                                 for (x=0; x<gridSize-1; x++) {
454                                         MFace *mf = &dlm->mface[i];
455                                         mf->v1 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
456                                         mf->v2 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize);
457                                         mf->v3 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
458                                         mf->v4 = getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize);
459                                         mf->mat_nr = mat_nr;
460                                         mf->flag = flag;
461                                         mf->edcode = 0;
462
463                                         if (faceMap) {
464                                                 faceMap[i] = ccgDM_getFaceHandle(ccgdm, f);
465                                         }
466
467                                         if (x+1==gridSize-1)
468                                                 mf->edcode|= ME_V2V3;
469                                         if (y+1==gridSize-1)
470                                                 mf->edcode|= ME_V1V2;
471
472                                         for (j=0; j<4; j++) {
473                                                 int fx = x + (j==1||j==2);
474                                                 int fy = y + (j==0||j==1);
475                                                 float x_v = (float) fx/(gridSize-1);
476                                                 float y_v = (float) fy/(gridSize-1);
477                                                 float data[6];
478
479                                                 for (k=0; k<numDataComponents; k++) {
480                                                         data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
481                                                                         (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
482                                                 }
483
484                                                 if (dlm->tface) {
485                                                         TFace *tf = &dlm->tface[i];
486                                                         unsigned char col[4];
487                                                         col[0] = (int) (data[0]*255);
488                                                         col[1] = (int) (data[1]*255);
489                                                         col[2] = (int) (data[2]*255);
490                                                         col[3] = (int) (data[3]*255);
491                                                         tf->col[j] = *((unsigned int*) col);
492                                                         tf->uv[j][0] = data[4];
493                                                         tf->uv[j][1] = data[5];
494                                                 } else if (dlm->mcol) {
495                                                         unsigned char *col = (unsigned char*) &dlm->mcol[i*4+j];
496                                                         col[0] = (int) (data[0]*255);
497                                                         col[1] = (int) (data[1]*255);
498                                                         col[2] = (int) (data[2]*255);
499                                                         col[3] = (int) (data[3]*255);
500                                                 }
501                                         }
502                                         if (dlm->tface) {
503                                                 TFace *tf = &dlm->tface[i];
504                                                 tf->tpage = origTFace->tpage;
505                                                 tf->flag = origTFace->flag;
506                                                 tf->transp = origTFace->transp;
507                                                 tf->mode = origTFace->mode;
508                                                 tf->tile = origTFace->tile;
509                                         }
510
511                                         i++;
512                                 }
513                         }
514                 }
515         }
516         ccgFaceIterator_free(fi);
517
518         mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
519
520         return dlm;
521 }
522
523 static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float (*vertexCos)[3], int useFlatSubdiv) {
524         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
525         CCGVertHDL fVerts[4];
526         MVert *mvert = dlm?dlm->mvert:me->mvert;
527         MEdge *medge = dlm?dlm->medge:me->medge;
528         MFace *mface = dlm?dlm->mface:me->mface;
529         int totvert = dlm?dlm->totvert:me->totvert;
530         int totedge = dlm?dlm->totedge:me->totedge;
531         int totface = dlm?dlm->totface:me->totface;
532         int i;
533
534         ccgSubSurf_initFullSync(ss);
535
536         if (vertexCos) {
537                 for (i=0; i<totvert; i++) {
538                         ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos[i]);
539                 }
540         } else {
541                 for (i=0; i<totvert; i++) {
542                         ccgSubSurf_syncVert(ss, (CCGVertHDL) i, mvert[i].co);
543                 }
544         }
545
546         if (medge) {
547                 for (i=0; i<totedge; i++) {
548                         MEdge *med = &medge[i];
549                         float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
550
551                         ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease);
552                 }
553         } else {
554                 for (i=0; i<totface; i++) {
555                         MFace *mf = &((MFace*) mface)[i];
556
557                         if (!mf->v3) {
558                                 ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0f);
559                         }
560                 }
561         }
562
563         for (i=0; i<totface; i++) {
564                 MFace *mf = &((MFace*) mface)[i];
565
566                 if (mf->v3) {
567                         fVerts[0] = (CCGVertHDL) mf->v1;
568                         fVerts[1] = (CCGVertHDL) mf->v2;
569                         fVerts[2] = (CCGVertHDL) mf->v3;
570                         fVerts[3] = (CCGVertHDL) mf->v4;
571
572                         ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts);
573                 }
574         }
575
576         ccgSubSurf_processSync(ss);
577 }
578
579 void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], int useFlatSubdiv)
580 {
581         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
582         EditVert *ev, *fVerts[4];
583         EditEdge *ee;
584         EditFace *ef;
585
586         ccgSubSurf_initFullSync(ss);
587
588         if (vertCos) {
589                 int i=0;
590
591                 for (ev=em->verts.first; ev; ev=ev->next) {
592                         ccgSubSurf_syncVert(ss, ev, vertCos[i++]);
593                 }
594         } else {
595                 for (ev=em->verts.first; ev; ev=ev->next) {
596                         ccgSubSurf_syncVert(ss, ev, ev->co);
597                 }
598         }
599
600         for (ee=em->edges.first; ee; ee=ee->next) {
601                 ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor);
602         }
603
604         for (ef=em->faces.first; ef; ef=ef->next) {
605                 fVerts[0] = ef->v1;
606                 fVerts[1] = ef->v2;
607                 fVerts[2] = ef->v3;
608                 fVerts[3] = ef->v4;
609
610                 ccgSubSurf_syncFace(ss, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
611         }
612
613         ccgSubSurf_processSync(ss);
614 }
615
616 /***/
617
618 struct CCGDerivedMesh {
619         DerivedMesh dm;
620
621         CCGSubSurf *ss;
622         int fromEditmesh, drawInteriorEdges;
623
624         Mesh *me;
625         DispListMesh *dlm;
626
627         EditVert **vertMap;
628         EditEdge **edgeMap;
629         EditFace **faceMap;
630 };
631
632 static EditVert *ccgDM_getVertHandle(CCGDerivedMesh *ccgdm, CCGVert *v) {
633         if (ccgdm->vertMap) {
634                 int index = (int) ccgSubSurf_getVertVertHandle(ccgdm->ss, v);
635
636                 return ccgdm->vertMap[index];
637         } else {
638                 return ccgSubSurf_getVertVertHandle(ccgdm->ss, v);
639         }
640 }
641 static EditEdge *ccgDM_getEdgeHandle(CCGDerivedMesh *ccgdm, CCGEdge *e) {
642         if (ccgdm->vertMap) {
643                 int index = (int) ccgSubSurf_getEdgeEdgeHandle(ccgdm->ss, e);
644
645                 return ccgdm->edgeMap[index];
646         } else {
647                 return ccgSubSurf_getEdgeEdgeHandle(ccgdm->ss, e);
648         }
649 }
650 static EditFace *ccgDM_getFaceHandle(CCGDerivedMesh *ccgdm, CCGFace *f) {
651         if (ccgdm->vertMap) {
652                 int index = (int) ccgSubSurf_getFaceFaceHandle(ccgdm->ss, f);
653
654                 return ccgdm->faceMap[index];
655         } else {
656                 return ccgSubSurf_getFaceFaceHandle(ccgdm->ss, f);
657         }
658 }
659
660 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
661         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
662         CCGSubSurf *ss = ccgdm->ss;
663         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
664         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
665         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
666         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
667         int gridSize = ccgSubSurf_getGridSize(ss);
668
669         if (!ccgSubSurf_getNumVerts(ss))
670                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
671
672         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
673                 CCGVert *v = ccgVertIterator_getCurrent(vi);
674                 float *co = ccgSubSurf_getVertData(ss, v);
675
676                 DO_MINMAX(co, min_r, max_r);
677         }
678
679         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
680                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
681                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
682
683                 for (i=0; i<edgeSize; i++)
684                         DO_MINMAX(edgeData[i].co, min_r, max_r);
685         }
686
687         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
688                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
689                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
690
691                 for (S=0; S<numVerts; S++) {
692                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
693
694                         for (y=0; y<gridSize; y++)
695                                 for (x=0; x<gridSize; x++)
696                                         DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
697                 }
698         }
699
700         ccgFaceIterator_free(fi);
701         ccgEdgeIterator_free(ei);
702         ccgVertIterator_free(vi);
703 }
704 static int ccgDM_getNumVerts(DerivedMesh *dm) {
705         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
706
707         return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
708 }
709 static int ccgDM_getNumFaces(DerivedMesh *dm) {
710         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
711
712         return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
713 }
714 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
715         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
716         CCGSubSurf *ss = ccgdm->ss;
717         int edgeSize = ccgSubSurf_getEdgeSize(ss);
718         int gridSize = ccgSubSurf_getGridSize(ss);
719         int i;
720         CCGVertIterator *vi;
721         CCGEdgeIterator *ei;
722         CCGFaceIterator *fi;
723
724         i = 0;
725         vi = ccgSubSurf_getVertIterator(ss);
726         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
727                 CCGVert *v = ccgVertIterator_getCurrent(vi);
728                 VecCopyf(cos[i++], ccgSubSurf_getVertData(ss, v));
729         }
730         ccgVertIterator_free(vi);
731
732         ei = ccgSubSurf_getEdgeIterator(ss);
733         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
734                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
735                 int x;
736
737                 for (x=1; x<edgeSize-1; x++)
738                         VecCopyf(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
739         }
740         ccgEdgeIterator_free(ei);
741
742         fi = ccgSubSurf_getFaceIterator(ss);
743         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
744                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
745                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
746
747                 VecCopyf(cos[i++], ccgSubSurf_getFaceCenterData(ss, f));
748                 for (S=0; S<numVerts; S++)
749                         for (x=1; x<gridSize-1; x++)
750                                 VecCopyf(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
751                 for (S=0; S<numVerts; S++)
752                         for (y=1; y<gridSize-1; y++)
753                                 for (x=1; x<gridSize-1; x++)
754                                         VecCopyf(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
755         }
756         ccgFaceIterator_free(fi);
757 }
758 static void ccgDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData) {
759         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
760         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
761
762         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
763                 CCGVert *v = ccgVertIterator_getCurrent(vi);
764                 VertData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
765
766                 func(userData, ccgDM_getVertHandle(ccgdm, v), vd->co, vd->no, NULL);
767         }
768
769         ccgVertIterator_free(vi);
770 }
771 static void ccgDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData) {
772         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
773         CCGSubSurf *ss = ccgdm->ss;
774         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
775         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
776
777         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
778                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
779                 EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e);
780                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
781
782                 for (i=0; i<edgeSize-1; i++)
783                         func(userData, edge, edgeData[i].co, edgeData[i+1].co);
784         }
785
786         ccgEdgeIterator_free(ei);
787 }
788 static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm, int allowShared) {
789         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
790
791         return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm, NULL, NULL, NULL);
792 }
793 static DispListMesh *ccgDM_convertToDispListMeshMapped(DerivedMesh *dm, int allowShared, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) {
794         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
795
796         return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm, vertMap_r, edgeMap_r, faceMap_r);
797 }
798
799 static void ccgDM_drawVerts(DerivedMesh *dm) {
800         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
801         CCGSubSurf *ss = ccgdm->ss;
802         int edgeSize = ccgSubSurf_getEdgeSize(ss);
803         int gridSize = ccgSubSurf_getGridSize(ss);
804         CCGVertIterator *vi;
805         CCGEdgeIterator *ei;
806         CCGFaceIterator *fi;
807
808         glBegin(GL_POINTS);
809         vi = ccgSubSurf_getVertIterator(ss);
810         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
811                 CCGVert *v = ccgVertIterator_getCurrent(vi);
812                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
813         }
814         ccgVertIterator_free(vi);
815
816         ei = ccgSubSurf_getEdgeIterator(ss);
817         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
818                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
819                 int x;
820
821                 for (x=1; x<edgeSize-1; x++)
822                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
823         }
824         ccgEdgeIterator_free(ei);
825
826         fi = ccgSubSurf_getFaceIterator(ss);
827         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
828                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
829                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
830
831                 glVertex3fv(ccgSubSurf_getFaceCenterData(ss, f));
832                 for (S=0; S<numVerts; S++)
833                         for (x=1; x<gridSize-1; x++)
834                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
835                 for (S=0; S<numVerts; S++)
836                         for (y=1; y<gridSize-1; y++)
837                                 for (x=1; x<gridSize-1; x++)
838                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
839         }
840         ccgFaceIterator_free(fi);
841         glEnd();
842 }
843 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
844         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
845         CCGSubSurf *ss = ccgdm->ss;
846         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
847         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
848         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
849         int gridSize = ccgSubSurf_getGridSize(ss);
850         int useAging;
851
852         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
853
854         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
855                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
856                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
857
858                 if (ccgdm->fromEditmesh) {
859                         EditEdge *eed = ccgDM_getEdgeHandle(ccgdm, e);
860                         if (eed && eed->h!=0)
861                                 continue;
862                 }
863                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(ss, e))
864                         continue;
865
866                 if (useAging && !(G.f&G_BACKBUFSEL)) {
867                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
868                         glColor3ub(0, ageCol>0?ageCol:0, 0);
869                 }
870
871                 glBegin(GL_LINE_STRIP);
872                 for (i=0; i<edgeSize-1; i++) {
873                         glVertex3fv(edgeData[i].co);
874                         glVertex3fv(edgeData[i+1].co);
875                 }
876                 glEnd();
877         }
878
879         if (useAging && !(G.f&G_BACKBUFSEL)) {
880                 glColor3ub(0, 0, 0);
881         }
882
883         if (ccgdm->drawInteriorEdges) {
884                 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
885                         CCGFace *f = ccgFaceIterator_getCurrent(fi);
886                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
887
888                         if (ccgdm->fromEditmesh) {
889                                 EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
890                                 if (efa && efa->h!=0)
891                                         continue;
892                         }
893
894                         for (S=0; S<numVerts; S++) {
895                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
896
897                                 glBegin(GL_LINE_STRIP);
898                                 for (x=0; x<gridSize; x++)
899                                         glVertex3fv(faceGridData[x].co);
900                                 glEnd();
901                                 for (y=1; y<gridSize-1; y++) {
902                                         glBegin(GL_LINE_STRIP);
903                                         for (x=0; x<gridSize; x++)
904                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
905                                         glEnd();
906                                 }
907                                 for (x=1; x<gridSize-1; x++) {
908                                         glBegin(GL_LINE_STRIP);
909                                         for (y=0; y<gridSize; y++)
910                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
911                                         glEnd();
912                                 }
913                         }
914                 }
915         }
916
917         ccgFaceIterator_free(fi);
918         ccgEdgeIterator_free(ei);
919 }
920 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
921         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
922         CCGSubSurf *ss = ccgdm->ss;
923         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
924         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
925
926         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
927                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
928
929                 if (!ccgSubSurf_getEdgeNumFaces(ss, e)) {
930                         VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
931
932                         glBegin(GL_LINE_STRIP);
933                         for (i=0; i<edgeSize-1; i++) {
934                                 glVertex3fv(edgeData[i].co);
935                                 glVertex3fv(edgeData[i+1].co);
936                         }
937                         glEnd();
938                 }
939         }
940
941         ccgEdgeIterator_free(ei);
942 }
943
944 static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
945         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
946         CCGSubSurf *ss = ccgdm->ss;
947         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
948         int gridSize = ccgSubSurf_getGridSize(ss);
949
950         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
951                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
952                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
953                 unsigned char flag,mat_nr;
954
955                 if (ccgdm->fromEditmesh || ccgdm->vertMap) {
956                         EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
957                         if (efa && efa->h!=0)
958                                 continue;
959
960                         flag = efa->flag;
961                         mat_nr = efa->mat_nr;
962                 } else {
963                         int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
964                         MFace *mf = (ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface) + index;
965                         flag = mf->flag;
966                         mat_nr = mf->mat_nr;
967                 }
968
969                 if (!setMaterial(mat_nr+1))
970                         continue;
971
972                 glShadeModel((flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT);
973                 for (S=0; S<numVerts; S++) {
974                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
975
976                         if (flag&ME_SMOOTH) {
977                                 for (y=0; y<gridSize-1; y++) {
978                                         glBegin(GL_QUAD_STRIP);
979                                         for (x=0; x<gridSize; x++) {
980                                                 VertData *a = &faceGridData[(y+0)*gridSize + x];
981                                                 VertData *b = &faceGridData[(y+1)*gridSize + x];
982
983                                                 glNormal3fv(a->no);
984                                                 glVertex3fv(a->co);
985                                                 glNormal3fv(b->no);
986                                                 glVertex3fv(b->co);
987                                         }
988                                         glEnd();
989                                 }
990                         } else {
991                                 glBegin(GL_QUADS);
992                                 for (y=0; y<gridSize-1; y++) {
993                                         for (x=0; x<gridSize-1; x++) {
994                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
995                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
996                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
997                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
998                                                 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
999                                                 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1000                                                 float no[3];
1001
1002                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1003                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1004                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
1005                                                 glNormal3fv(no);
1006
1007                                                 glVertex3fv(d);
1008                                                 glVertex3fv(c);
1009                                                 glVertex3fv(b);
1010                                                 glVertex3fv(a);
1011                                         }
1012                                 }
1013                                 glEnd();
1014                         }
1015                 }
1016         }
1017
1018         ccgFaceIterator_free(fi);
1019 }
1020 static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
1021         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1022         CCGSubSurf *ss = ccgdm->ss;
1023         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1024         int gridSize = ccgSubSurf_getGridSize(ss);
1025         unsigned char *cp1, *cp2;
1026         int useTwoSide=1;
1027
1028         cp1= col1;
1029         if(col2) {
1030                 cp2= col2;
1031         } else {
1032                 cp2= NULL;
1033                 useTwoSide= 0;
1034         }
1035
1036         glShadeModel(GL_SMOOTH);
1037         if(col1 && col2)
1038                 glEnable(GL_CULL_FACE);
1039
1040         glBegin(GL_QUADS);
1041         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1042                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1043                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1044
1045                 for (S=0; S<numVerts; S++) {
1046                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1047                         for (y=0; y<gridSize-1; y++) {
1048                                 for (x=0; x<gridSize-1; x++) {
1049                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1050                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1051                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1052                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1053
1054                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1055                                         glVertex3fv(d);
1056                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1057                                         glVertex3fv(c);
1058                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1059                                         glVertex3fv(b);
1060                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1061                                         glVertex3fv(a);
1062
1063                                         if (useTwoSide) {
1064                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1065                                                 glVertex3fv(a);
1066                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1067                                                 glVertex3fv(b);
1068                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1069                                                 glVertex3fv(c);
1070                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1071                                                 glVertex3fv(d);
1072                                         }
1073
1074                                         if (cp2) cp2+=16;
1075                                         cp1+=16;
1076                                 }
1077                         }
1078                 }
1079         }
1080         glEnd();
1081
1082         ccgFaceIterator_free(fi);
1083 }
1084 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) {
1085         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1086         CCGSubSurf *ss = ccgdm->ss;
1087         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1088         int gridSize = ccgSubSurf_getGridSize(ss);
1089         MFace *mface = ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface;
1090         TFace *tface = ccgdm->dlm?ccgdm->dlm->tface:ccgdm->me->tface;
1091         MCol *mcol = ccgdm->dlm?ccgdm->dlm->mcol:ccgdm->me->mcol;
1092 //      float uv[4][2];
1093 //      float col[4][3];
1094
1095         glBegin(GL_QUADS);
1096         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1097                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1098                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1099                 int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
1100                 MFace *mf = &mface[index];
1101                 TFace *tf = tface?&tface[index]:NULL;
1102                 unsigned char *cp= NULL;
1103                 
1104                 if(tf && ((tf->flag&TF_HIDE) || (tf->mode&TF_INVISIBLE))) continue;
1105
1106                 if (setDrawParams(tf, mf->mat_nr)) {
1107                         if (tf) {
1108                                 cp= (unsigned char *) tf->col;
1109                         } else if (mcol) {
1110                                 cp= (unsigned char *) &mcol[index*4];
1111                         }
1112                 }
1113
1114                 for (S=0; S<numVerts; S++) {
1115                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1116                         for (y=0; y<gridSize-1; y++) {
1117                                 for (x=0; x<gridSize-1; x++) {
1118                                         VertData *a = &faceGridData[(y+0)*gridSize + x];
1119                                         VertData *b = &faceGridData[(y+0)*gridSize + x + 1];
1120                                         VertData *c = &faceGridData[(y+1)*gridSize + x + 1];
1121                                         VertData *d = &faceGridData[(y+1)*gridSize + x];
1122
1123                                         if (!(mf->flag&ME_SMOOTH)) {
1124                                                 float a_cX = c->co[0]-a->co[0], a_cY = c->co[1]-a->co[1], a_cZ = c->co[2]-a->co[2];
1125                                                 float b_dX = d->co[0]-b->co[0], b_dY = d->co[1]-b->co[1], b_dZ = d->co[2]-b->co[2];
1126                                                 float no[3];
1127
1128                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1129                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1130                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
1131
1132                                                 glNormal3fv(no);
1133                                         }
1134
1135 //                                      if (tf) glTexCoord2fv(tf->uv[0]);
1136 //                                      if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1137 //                                      if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
1138 //                                      glVertex3fv(mvert[mf->v1].co);
1139
1140 /*
1141                                         {
1142                                                 float x_v = (float) fx/(gridSize-1);
1143                                                 float y_v = (float) fy/(gridSize-1);
1144                                                 float data[6];
1145
1146                                                 for (k=0; k<numDataComponents; k++) {
1147                                                         data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
1148                                                                         (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
1149                                         }
1150 */
1151
1152 //                                      if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1153                                         if (mf->flag&ME_SMOOTH) glNormal3fv(d->no);
1154                                         glVertex3fv(d->co);
1155 //                                      if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1156                                         if (mf->flag&ME_SMOOTH) glNormal3fv(c->no);
1157                                         glVertex3fv(c->co);
1158 //                                      if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1159                                         if (mf->flag&ME_SMOOTH) glNormal3fv(b->no);
1160                                         glVertex3fv(b->co);
1161 //                                      if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1162                                         if (mf->flag&ME_SMOOTH) glNormal3fv(a->no);
1163                                         glVertex3fv(a->co);
1164                                 }
1165                         }
1166                 }
1167         }
1168         glEnd();
1169
1170         ccgFaceIterator_free(fi);
1171 /*
1172         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
1173         Mesh *me = mdm->me;
1174         MVert *mvert= mdm->verts;
1175         MFace *mface= me->mface;
1176         TFace *tface = me->tface;
1177         float *nors = mdm->nors;
1178         int a;
1179
1180         for (a=0; a<me->totface; a++) {
1181                 MFace *mf= &mface[a];
1182                 if (tf) glTexCoord2fv(tf->uv[1]);
1183                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1184                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
1185                 glVertex3fv(mvert[mf->v2].co);
1186
1187                 if (tf) glTexCoord2fv(tf->uv[2]);
1188                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1189                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
1190                 glVertex3fv(mvert[mf->v3].co);
1191
1192                 if(mf->v4) {
1193                         if (tf) glTexCoord2fv(tf->uv[3]);
1194                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1195                         if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
1196                         glVertex3fv(mvert[mf->v4].co);
1197                 }
1198                 glEnd();
1199         }
1200 */
1201 }
1202
1203 static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) {
1204         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1205         CCGSubSurf *ss = ccgdm->ss;
1206         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1207         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1208
1209         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1210
1211         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1212                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1213                 EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e);
1214                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1215
1216                 glBegin(GL_LINE_STRIP);
1217                 if (edge && (!setDrawOptions || setDrawOptions(userData, edge))) {
1218                         if (useAging && !(G.f&G_BACKBUFSEL)) {
1219                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1220                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
1221                         }
1222
1223                         for (i=0; i<edgeSize-1; i++) {
1224                                 glVertex3fv(edgeData[i].co);
1225                                 glVertex3fv(edgeData[i+1].co);
1226                         }
1227                 }
1228                 glEnd();
1229         }
1230
1231         ccgEdgeIterator_free(ei);
1232 }
1233 static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void (*setDrawInterpOptions)(void *userData, EditEdge *edge, float t), void *userData) {
1234         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1235         CCGSubSurf *ss = ccgdm->ss;
1236         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1237         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1238
1239         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1240
1241         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1242                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1243                 EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e);
1244                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1245
1246                 glBegin(GL_LINE_STRIP);
1247                 if (edge && (!setDrawOptions || setDrawOptions(userData, edge))) {
1248                         for (i=0; i<edgeSize; i++) {
1249                                 setDrawInterpOptions(userData, edge, (float) i/(edgeSize-1));
1250
1251                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1252                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1253                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1254                                 }
1255
1256                                 glVertex3fv(edgeData[i].co);
1257                         }
1258                 }
1259                 glEnd();
1260         }
1261 }
1262 static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) {
1263         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1264         CCGSubSurf *ss = ccgdm->ss;
1265         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1266         int gridSize = ccgSubSurf_getGridSize(ss);
1267
1268         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1269                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1270                 EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
1271                 if (efa && (!setDrawOptions || setDrawOptions(userData, efa))) {
1272                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1273
1274                         for (S=0; S<numVerts; S++) {
1275                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1276
1277                                 for (y=0; y<gridSize-1; y++) {
1278                                         glBegin(GL_QUAD_STRIP);
1279                                         for (x=0; x<gridSize; x++) {
1280                                                 glVertex3fv(faceGridData[(y+0)*gridSize + x].co);
1281                                                 glVertex3fv(faceGridData[(y+1)*gridSize + x].co);
1282                                         }
1283                                         glEnd();
1284                                 }
1285                         }
1286                 }
1287         }
1288
1289         ccgFaceIterator_free(fi);
1290 }
1291 static void ccgDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData) {
1292         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1293         CCGSubSurf *ss = ccgdm->ss;
1294         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1295
1296         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1297                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1298                 EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
1299
1300                 if (efa) {
1301                                 /* Face center data normal isn't updated atm. */
1302                         VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
1303
1304                         func(userData, efa, vd->co, vd->no);
1305                 }
1306         }
1307
1308         ccgFaceIterator_free(fi);
1309 }
1310
1311 static void ccgDM_release(DerivedMesh *dm) {
1312         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1313
1314         if (ccgdm->dlm) displistmesh_free(ccgdm->dlm);
1315         if (ccgdm->vertMap) {
1316                 MEM_freeN(ccgdm->vertMap);
1317                 MEM_freeN(ccgdm->edgeMap);
1318                 MEM_freeN(ccgdm->faceMap);
1319         }
1320
1321         MEM_freeN(ccgdm);
1322 }
1323
1324 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int drawInteriorEdges, Mesh *me, DispListMesh *dlm, EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) {
1325         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
1326
1327         ccgdm->dm.getMinMax = ccgDM_getMinMax;
1328         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
1329         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
1330         ccgdm->dm.getVertCos = ccgdm_getVertCos;
1331         ccgdm->dm.foreachMappedVertEM = ccgDM_foreachMappedVertEM;
1332         ccgdm->dm.foreachMappedEdgeEM = ccgDM_foreachMappedEdgeEM;
1333         ccgdm->dm.foreachMappedFaceCenterEM = ccgDM_foreachMappedFaceCenterEM;
1334         ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh;
1335         ccgdm->dm.convertToDispListMeshMapped = ccgDM_convertToDispListMeshMapped;
1336
1337         ccgdm->dm.drawVerts = ccgDM_drawVerts;
1338         ccgdm->dm.drawEdges = ccgDM_drawEdges;
1339         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
1340         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
1341         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
1342         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
1343
1344         ccgdm->dm.drawMappedEdgesInterpEM = ccgDM_drawMappedEdgesInterpEM;
1345         ccgdm->dm.drawMappedEdgesEM = ccgDM_drawMappedEdgesEM;
1346         ccgdm->dm.drawMappedFacesEM = ccgDM_drawMappedFacesEM;
1347
1348         ccgdm->dm.release = ccgDM_release;
1349         
1350         ccgdm->ss = ss;
1351         ccgdm->fromEditmesh = fromEditmesh;
1352         ccgdm->drawInteriorEdges = drawInteriorEdges;
1353         ccgdm->me = me;
1354         ccgdm->dlm = dlm;
1355         ccgdm->vertMap = vertMap;
1356         ccgdm->edgeMap = edgeMap;
1357         ccgdm->faceMap = faceMap;
1358
1359         return ccgdm;
1360 }
1361
1362 /***/
1363
1364 DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd, float (*vertCos)[3]) {
1365         int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
1366         int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
1367         int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
1368
1369         smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, 0, useSimple);
1370         ss_sync_from_editmesh(smd->emCache, em, vertCos, useSimple);
1371
1372         return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, drawInteriorEdges, NULL, NULL, NULL, NULL, NULL);
1373 }
1374
1375 DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) {
1376         int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
1377         int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
1378         int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
1379                 
1380         smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, 0, useSimple);
1381
1382         ss_sync_from_mesh(smd->emCache, NULL, dlm, vertCos, useSimple);
1383
1384         return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, drawInteriorEdges, NULL, dlm, vertMap, edgeMap, faceMap);
1385 }
1386
1387 DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) {
1388         int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
1389         int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
1390         DispListMesh *ndlm;
1391
1392                 /* Do not use cache in render mode. */
1393         if (useRenderParams) {
1394                 CCGSubSurf *ss = _getSubSurf(NULL, smd->renderLevels, 0, 1, 1, useSimple);
1395
1396                 ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
1397
1398                 ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm, NULL, NULL, NULL);
1399                 if (dlm) displistmesh_free(dlm);
1400
1401                 ccgSubSurf_free(ss);
1402                 
1403                 return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
1404         } else {
1405                 int useEdgeCreation = !(dlm?dlm->medge:me->medge);
1406                 int useIncremental = (smd->flags&eSubsurfModifierFlag_Incremental) && !useEdgeCreation;
1407                 int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
1408                 CCGSubSurf *ss;
1409                 
1410                         /* It is quite possible there is a much better place to do this. It
1411                          * depends a bit on how rigourously we expect this function to never
1412                          * be called in editmode. In semi-theory we could share a single
1413                          * cache, but the handles used inside and outside editmode are not
1414                          * the same so we would need some way of converting them. Its probably
1415                          * not worth the effort. But then why am I even writing this long
1416                          * comment that no one will read? Hmmm. - zr
1417                          */
1418                 if (smd->emCache) {
1419                         ccgSubSurf_free(smd->emCache);
1420                         smd->emCache = NULL;
1421                 }
1422
1423                 if (useIncremental && isFinalCalc) {
1424                         smd->mCache = ss = _getSubSurf(smd->mCache, smd->levels, useAging, 0, 0, useSimple);
1425
1426                         ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
1427
1428                         return (DerivedMesh*) getCCGDerivedMesh(ss, 0, drawInteriorEdges, me, dlm, NULL, NULL, NULL);
1429                 } else {
1430                         if (smd->mCache && isFinalCalc) {
1431                                 ccgSubSurf_free(smd->mCache);
1432                                 smd->mCache = NULL;
1433                         }
1434
1435                         ss = _getSubSurf(NULL, smd->levels, 0, 1, useEdgeCreation, useSimple);
1436                         ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
1437                         ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm, NULL, NULL, NULL);
1438
1439                         if (dlm) displistmesh_free(dlm);
1440                         ccgSubSurf_free(ss);
1441
1442                         return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
1443                 }
1444         }
1445 }
1446
1447 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
1448 {
1449                 /* Finds the subsurf limit positions for the verts in a mesh 
1450                  * and puts them in an array of floats. Please note that the 
1451                  * calculated vert positions is incorrect for the verts 
1452                  * on the boundary of the mesh.
1453                  */
1454         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0, 0);
1455         float edge_sum[3], face_sum[3];
1456         CCGVertIterator *vi;
1457
1458         ss_sync_from_mesh(ss, me, NULL, NULL, 0);
1459
1460         vi = ccgSubSurf_getVertIterator(ss);
1461         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1462                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1463                 int idx = (int) ccgSubSurf_getVertVertHandle(ss, v);
1464                 int N = ccgSubSurf_getVertNumEdges(ss, v);
1465                 int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
1466                 float *co;
1467                 int i;
1468                 
1469                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
1470                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
1471
1472                 for (i=0; i<N; i++) {
1473                         CCGEdge *e = ccgSubSurf_getVertEdge(ss, v, i);
1474                         VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
1475                 }
1476                 for (i=0; i<numFaces; i++) {
1477                         CCGFace *f = ccgSubSurf_getVertFace(ss, v, i);
1478                         VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss, f));
1479                 }
1480
1481                 co = ccgSubSurf_getVertData(ss, v);
1482                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
1483                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
1484                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
1485         }
1486         ccgVertIterator_free(vi);
1487
1488         ccgSubSurf_free(ss);
1489 }
1490