svn merge -r40166:40279 ^/trunk/blender
[blender.git] / source / blender / blenkernel / intern / subsurf_ccg.c
index 2ff555b..b262815 100644 (file)
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
+#include "BLI_utildefines.h"
 #include "BLI_blenlib.h"
 #include "BLI_edgehash.h"
 #include "BLI_math.h"
 #include "BLI_memarena.h"
 #include "BLI_pbvh.h"
-#include "BLI_utildefines.h"
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_global.h"
 #include "BKE_paint.h"
 #include "BKE_scene.h"
 #include "BKE_subsurf.h"
+#include "BKE_tessmesh.h"
+
+#include "PIL_time.h"
+#include "BLI_array.h"
 
 #include "GL/glew.h"
 
 
 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
 
-static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v);
-static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e);
-static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f);
+static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
+                                         int drawInteriorEdges,
+                                         int useSubsurfUv,
+                                         DerivedMesh *dm);
 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
 
 ///
@@ -161,7 +166,8 @@ static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
                return edgeBase + x-1;
        }
 }
-static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
+
+BM_INLINE int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
        int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
        int numVerts = ccgSubSurf_getFaceNumVerts(f);
 
@@ -216,10 +222,16 @@ static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGV
 }
 
 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MTFace *tface) {
-       MFace *mface = dm->getFaceArray(dm);
+#if 1 /*BMESH_TODO*/
+       (void)ss;
+       (void)origss;
+       (void)dm;
+       (void)tface;
+#else
+       MFace *mface = dm->getTessFaceArray(dm);
        MVert *mvert = dm->getVertArray(dm);
        int totvert = dm->getNumVerts(dm);
-       int totface = dm->getNumFaces(dm);
+       int totface = dm->getNumTessFaces(dm);
        int i, j, seam;
        UvMapVert *v;
        UvVertMap *vmap;
@@ -309,6 +321,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
        free_uv_vert_map(vmap);
        ccgSubSurf_processSync(ss);
 
+#endif
        return 1;
 }
 
@@ -382,65 +395,123 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
 }
 
 /* face weighting */
-static void calc_ss_weights(int gridFaces,
-                                                       FaceVertWeight **qweight, FaceVertWeight **tweight)
+typedef struct FaceVertWeightEntry {
+       FaceVertWeight *weight;
+       float *w;
+       int valid;
+} FaceVertWeightEntry;
+
+typedef struct WeightTable {
+       FaceVertWeightEntry *weight_table;
+       int len;
+} WeightTable;
+
+static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
 {
-       FaceVertWeight *qw, *tw;
-       int x, y, j;
-       int numWeights = gridFaces * gridFaces;
-
-       *tweight = MEM_mallocN(sizeof(**tweight) * numWeights, "ssTriWeight");
-       *qweight = MEM_mallocN(sizeof(**qweight) * numWeights, "ssQuadWeight");
-
-       qw = *qweight;
-       tw = *tweight;
-
-       for (y = 0; y < gridFaces; y++) {
-               for (x = 0; x < gridFaces; x++) {
-                       for (j = 0; j < 4; j++) {
-                               int fx = x + (j == 2 || j == 3);
-                               int fy = y + (j == 1 || j == 2);
-                               float x_v = (float) fx / gridFaces;
-                               float y_v = (float) fy / gridFaces;
-                               float tx_v = (1.0f - x_v), ty_v = (1.0f - y_v);
-                               float center = (1.0f / 3.0f) * tx_v * ty_v;
-
-                               (*tw)[j][0] = center + 0.5f * tx_v * y_v;
-                               (*tw)[j][2] = center + 0.5f * x_v * ty_v;
-                               (*tw)[j][1] = 1.0f - (*tw)[j][0] - (*tw)[j][2];
-                               (*tw)[j][3] = 0.0f;
-
-                               tx_v *= 0.5f;
-                               ty_v *= 0.5f;
-
-                               (*qw)[j][3] = tx_v * ty_v;
-                               (*qw)[j][0] = (*qw)[j][3] + tx_v * y_v;
-                               (*qw)[j][2] = (*qw)[j][3] + x_v * ty_v;
-                               (*qw)[j][1] = 1.0f - (*qw)[j][0] - (*qw)[j][2] - (*qw)[j][3];
+       int x, y, i, j;
+       float *w, w1, w2, w4, fac, fac2, fx, fy;
+
+       if (wtable->len <= faceLen) {
+               void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry)*(faceLen+1), "weight table alloc 2");
+               
+               if (wtable->len) {
+                       memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry)*wtable->len);
+                       MEM_freeN(wtable->weight_table);
+               }
+               
+               wtable->weight_table = tmp;
+               wtable->len = faceLen+1;
+       }
 
+       if (!wtable->weight_table[faceLen].valid) {
+               wtable->weight_table[faceLen].valid = 1;
+               wtable->weight_table[faceLen].w = w = MEM_callocN(sizeof(float)*faceLen*faceLen*(gridCuts+2)*(gridCuts+2), "weight table alloc");
+               fac = 1.0f / (float)faceLen;
+
+               for (i=0; i<faceLen; i++) {
+                       for (x=0; x<gridCuts+2; x++) {
+                               for (y=0; y<gridCuts+2; y++) {
+                                       fx = 0.5f - (float)x / (float)(gridCuts+1) / 2.0f;
+                                       fy = 0.5f - (float)y / (float)(gridCuts+1) / 2.0f;
+                               
+                                       fac2 = faceLen - 4;
+                                       w1 = (1.0f - fx) * (1.0f - fy) + (-fac2*fx*fy*fac);
+                                       w2 = (1.0f - fx + fac2*fx*-fac) * (fy);
+                                       w4 = (fx) * (1.0f - fy + -fac2*fy*fac);
+                                       
+                                       fac2 = 1.0f - (w1+w2+w4);
+                                       fac2 = fac2 / (float)(faceLen-3);
+                                       for (j=0; j<faceLen; j++)
+                                               w[j] = fac2;
+                                       
+                                       w[i] = w1;
+                                       w[(i-1+faceLen)%faceLen] = w2;
+                                       w[(i+1)%faceLen] = w4;
+
+                                       w += faceLen;
+                               }
                        }
-                       tw++;
-                       qw++;
                }
        }
+
+       return wtable->weight_table[faceLen].w;
+}
+
+static void free_ss_weights(WeightTable *wtable)
+{
+       int i;
+
+       for (i=0; i<wtable->len; i++) {
+               if (wtable->weight_table[i].valid)
+                       MEM_freeN(wtable->weight_table[i].w);
+       }
+       
+       if (wtable->weight_table)
+               MEM_freeN(wtable->weight_table);
+}
+
+#if 0
+static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
+                                                                int drawInteriorEdges, int useSubsurfUv,
+                                                                DerivedMesh *dm, struct MultiresSubsurf *ms)
+{
+       DerivedMesh *cgdm, *result;
+       double curt = PIL_check_seconds_timer();
+
+       cgdm = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
+       result = CDDM_copy(cgdm, 1);
+
+       printf("subsurf conversion time: %.6lf\n", PIL_check_seconds_timer() - curt);
+
+       cgdm->needsFree = 1;
+       cgdm->release(cgdm);
+
+       CDDM_calc_normals(result);
+
+       return result;
 }
+#endif
 
-static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
+static int ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
                                                                         float (*vertexCos)[3], int useFlatSubdiv)
 {
        float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
-       CCGVertHDL fVerts[4];
-       int totvert = dm->getNumVerts(dm);
-       int totedge = dm->getNumEdges(dm);
-       int totface = dm->getNumFaces(dm);
-       int i;
-       int *index;
+       CCGVertHDL *fVerts = NULL;
+       BLI_array_declare(fVerts);
        MVert *mvert = dm->getVertArray(dm);
        MEdge *medge = dm->getEdgeArray(dm);
-       MFace *mface = dm->getFaceArray(dm);
+       /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
        MVert *mv;
        MEdge *me;
-       MFace *mf;
+       MLoop *mloop = dm->getLoopArray(dm), *ml;
+       MPoly *mpoly = dm->getPolyArray(dm), *mp;
+       /*MFace *mf;*/ /*UNUSED*/
+       int totvert = dm->getNumVerts(dm);
+       int totedge = dm->getNumEdges(dm);
+       /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
+       /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/
+       int i, j;
+       int *index;
 
        ccgSubSurf_initFullSync(ss);
 
@@ -473,38 +544,43 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
                ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index)? *index++: i;
        }
 
-       mf = mface;
-       index = (int *)dm->getFaceDataArray(dm, CD_ORIGINDEX);
-       for (i = 0; i < totface; i++, mf++) {
-               CCGFace *f;
+       mp = mpoly;
+       index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+       for (i=0; i<dm->numPolyData; i++, mp++) {
+               CCGFace *f=NULL;
+
+               BLI_array_empty(fVerts);
 
-               fVerts[0] = SET_INT_IN_POINTER(mf->v1);
-               fVerts[1] = SET_INT_IN_POINTER(mf->v2);
-               fVerts[2] = SET_INT_IN_POINTER(mf->v3);
-               fVerts[3] = SET_INT_IN_POINTER(mf->v4);
+               ml = mloop + mp->loopstart;
+               for (j=0; j<mp->totloop; j++, ml++) {
+                       BLI_array_append(fVerts, SET_INT_IN_POINTER(ml->v));
+               }
 
-               // this is very bad, means mesh is internally consistent.
-               // it is not really possible to continue without modifying
-               // other parts of code significantly to handle missing faces.
-               // since this really shouldn't even be possible we just bail.
-               if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), fVerts[3] ? 4 : 3,
+               /* this is very bad, means mesh is internally inconsistent.
+                * it is not really possible to continue without modifying
+                * other parts of code significantly to handle missing faces.
+                * since this really shouldn't even be possible we just bail.*/
+               if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), mp->totloop,
                                                           fVerts, &f) == eCCGError_InvalidValue) {
                        static int hasGivenError = 0;
 
                        if(!hasGivenError) {
-                               //XXX error("Unrecoverable error in SubSurf calculation,"
-                               //      " mesh is inconsistent.");
+                               printf("Unrecoverable error in SubSurf calculation,"
+                                          " mesh is inconsistent.\n");
 
                                hasGivenError = 1;
                        }
 
-                       return;
+                       return 0;
                }
 
-               ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = (index)? *index++: i;
+               ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = index ? *index++: i;
        }
 
        ccgSubSurf_processSync(ss);
+
+       BLI_array_free(fVerts);
+       return 1;
 }
 
 /***/
@@ -521,9 +597,9 @@ static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) {
        return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
 }
 
-static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+static void cgdm_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
@@ -565,32 +641,32 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
        ccgEdgeIterator_free(ei);
        ccgVertIterator_free(vi);
 }
-static int ccgDM_getNumVerts(DerivedMesh *dm) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+static int cgdm_getNumVerts(DerivedMesh *dm) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
 
-       return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
+       return ccgSubSurf_getNumFinalVerts(cgdm->ss);
 }
-static int ccgDM_getNumEdges(DerivedMesh *dm) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+static int cgdm_getNumEdges(DerivedMesh *dm) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
 
-       return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
+       return ccgSubSurf_getNumFinalEdges(cgdm->ss);
 }
-static int ccgDM_getNumFaces(DerivedMesh *dm) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+static int cgdm_getNumTessFaces(DerivedMesh *dm) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
 
-       return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
+       return ccgSubSurf_getNumFinalFaces(cgdm->ss);
 }
 
 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
 {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        DMGridData *vd;
        int i;
 
        memset(mv, 0, sizeof(*mv));
 
-       if((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
+       if((vertNum < cgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
                /* this vert comes from face data */
                int lastface = ccgSubSurf_getNumFaces(ss) - 1;
                CCGFace *f;
@@ -603,10 +679,10 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
                int gridInternalEnd;
 
                i = 0;
-               while(i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert)
+               while(i < lastface && vertNum >= cgdm->faceMap[i + 1].startVert)
                        ++i;
 
-               f = ccgdm->faceMap[i].face;
+               f = cgdm->faceMap[i].face;
                numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                gridSideVerts = gridSize - 2;
@@ -615,7 +691,7 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
                gridSideEnd = 1 + numVerts * gridSideVerts;
                gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
 
-               offset = vertNum - ccgdm->faceMap[i].startVert;
+               offset = vertNum - cgdm->faceMap[i].startVert;
                if(offset < 1) {
                        vd = ccgSubSurf_getFaceCenterData(f);
                        copy_v3_v3(mv->co, vd->co);
@@ -637,28 +713,28 @@ static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
                        copy_v3_v3(mv->co, vd->co);
                        normal_float_to_short_v3(mv->no, vd->no);
                }
-       } else if((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
+       } else if((vertNum < cgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
                /* this vert comes from edge data */
                CCGEdge *e;
                int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
                int x;
 
                i = 0;
-               while(i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert)
+               while(i < lastedge && vertNum >= cgdm->edgeMap[i + 1].startVert)
                        ++i;
 
-               e = ccgdm->edgeMap[i].edge;
+               e = cgdm->edgeMap[i].edge;
 
-               x = vertNum - ccgdm->edgeMap[i].startVert + 1;
+               x = vertNum - cgdm->edgeMap[i].startVert + 1;
                vd = ccgSubSurf_getEdgeData(ss, e, x);
                copy_v3_v3(mv->co, vd->co);
                normal_float_to_short_v3(mv->no, vd->no);
        } else {
                /* this vert comes from vert data */
                CCGVert *v;
-               i = vertNum - ccgdm->vertMap[0].startVert;
+               i = vertNum - cgdm->vertMap[0].startVert;
 
-               v = ccgdm->vertMap[i].vert;
+               v = cgdm->vertMap[i].vert;
                vd = ccgSubSurf_getVertData(ss, v);
                copy_v3_v3(mv->co, vd->co);
                normal_float_to_short_v3(mv->no, vd->no);
@@ -683,13 +759,13 @@ static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3])
 
 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
 {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        int i;
 
        memset(med, 0, sizeof(*med));
 
-       if(edgeNum < ccgdm->edgeMap[0].startEdge) {
+       if(edgeNum < cgdm->edgeMap[0].startEdge) {
                /* this edge comes from face data */
                int lastface = ccgSubSurf_getNumFaces(ss) - 1;
                CCGFace *f;
@@ -699,18 +775,48 @@ static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
                int edgeSize = ccgSubSurf_getEdgeSize(ss);
                int gridSideEdges;
                int gridInternalEdges;
+                               int lasti, previ;
+
+                               i = lastface;
+                               lasti = 0;
+                               while (1) {
+                                       previ = i;
+                                       if (cgdm->faceMap[i].startEdge >= edgeNum) {
+                                               i -= fabsf(i-lasti)/2.0f;
+                                       } else if (cgdm->faceMap[i].startEdge < edgeNum) {
+                                               i += fabsf(i-lasti)/2.0f;
+                                       } else {
+                                               break;
+                                       }
 
-               i = 0;
-               while(i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge)
+                                       if (i < 0) {
+                                               i = 0;
+                                               break;
+                                       }
+
+                                       if (i > lastface) {
+                                               i = lastface;
+                                               break;
+
+                                       }
+
+                                       if (i == lasti)
+                                          break;
+
+                                       lasti = previ;
+                               }
+
+                               i = i > 0 ? i - 1 : i;
+               while(i < lastface && edgeNum >= cgdm->faceMap[i + 1].startEdge)
                        ++i;
 
-               f = ccgdm->faceMap[i].face;
+               f = cgdm->faceMap[i].face;
                /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
 
                gridSideEdges = gridSize - 1;
                gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
 
-               offset = edgeNum - ccgdm->faceMap[i].startEdge;
+               offset = edgeNum - cgdm->faceMap[i].startEdge;
                grid = offset / (gridSideEdges + gridInternalEdges);
                offset %= (gridSideEdges + gridInternalEdges);
 
@@ -738,18 +844,18 @@ static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
                short *edgeFlag;
                unsigned int flags = 0;
 
-               i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
+               i = (edgeNum - cgdm->edgeMap[0].startEdge) / (edgeSize - 1);
 
-               e = ccgdm->edgeMap[i].edge;
+               e = cgdm->edgeMap[i].edge;
 
                if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
 
-               x = edgeNum - ccgdm->edgeMap[i].startEdge;
+               x = edgeNum - cgdm->edgeMap[i].startEdge;
 
                med->v1 = getEdgeIndex(ss, e, x, edgeSize);
                med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
 
-               edgeFlag = (ccgdm->edgeFlags)? &ccgdm->edgeFlags[i]: NULL;
+               edgeFlag = (cgdm->edgeFlags)? &cgdm->edgeFlags[i]: NULL;
                if(edgeFlag)
                        flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
                                         | ME_EDGEDRAW | ME_EDGERENDER;
@@ -762,8 +868,8 @@ static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
 
 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
 {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        int gridSize = ccgSubSurf_getGridSize(ss);
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int gridSideEdges = gridSize - 1;
@@ -774,19 +880,19 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
        int offset;
        int grid;
        int x, y;
-       int lastface = ccgSubSurf_getNumFaces(ss) - 1;
-       char *faceFlags = ccgdm->faceFlags;
+       /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
+       char *faceFlags = cgdm->faceFlags;
 
        memset(mf, 0, sizeof(*mf));
+       if (faceNum >= cgdm->dm.numFaceData)
+               return;
 
-       i = 0;
-       while(i < lastface && faceNum >= ccgdm->faceMap[i + 1].startFace)
-               ++i;
+       i = cgdm->reverseFaceMap[faceNum];
 
-       f = ccgdm->faceMap[i].face;
+       f = cgdm->faceMap[i].face;
        /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
 
-       offset = faceNum - ccgdm->faceMap[i].startFace;
+       offset = faceNum - cgdm->faceMap[i].startFace;
        grid = offset / gridFaces;
        offset %= gridFaces;
        y = offset / gridSideEdges;
@@ -806,8 +912,8 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
 
 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
 {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        DMGridData *vd;
        int index;
        int totvert, totedge, totface;
@@ -817,7 +923,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
 
        totface = ccgSubSurf_getNumFaces(ss);
        for(index = 0; index < totface; index++) {
-               CCGFace *f = ccgdm->faceMap[index].face;
+               CCGFace *f = cgdm->faceMap[index].face;
                int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                vd= ccgSubSurf_getFaceCenterData(f);
@@ -846,7 +952,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
 
        totedge = ccgSubSurf_getNumEdges(ss);
        for(index = 0; index < totedge; index++) {
-               CCGEdge *e = ccgdm->edgeMap[index].edge;
+               CCGEdge *e = cgdm->edgeMap[index].edge;
                int x;
 
                for(x = 1; x < edgeSize - 1; x++, i++) {
@@ -863,7 +969,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
 
        totvert = ccgSubSurf_getNumVerts(ss);
        for(index = 0; index < totvert; index++) {
-               CCGVert *v = ccgdm->vertMap[index].vert;
+               CCGVert *v = cgdm->vertMap[index].vert;
 
                vd= ccgSubSurf_getVertData(ss, v);
                copy_v3_v3(mvert[i].co, vd->co);
@@ -874,25 +980,25 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
 
 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
 {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        int index;
        int totedge, totface;
        int gridSize = ccgSubSurf_getGridSize(ss);
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int i = 0;
-       short *edgeFlags = ccgdm->edgeFlags;
+       short *edgeFlags = cgdm->edgeFlags;
 
        totface = ccgSubSurf_getNumFaces(ss);
        for(index = 0; index < totface; index++) {
-               CCGFace *f = ccgdm->faceMap[index].face;
+               CCGFace *f = cgdm->faceMap[index].face;
                int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                for(S = 0; S < numVerts; S++) {
                        for(x = 0; x < gridSize - 1; x++) {
                                MEdge *med = &medge[i];
 
-                               if(ccgdm->drawInteriorEdges)
+                               if(cgdm->drawInteriorEdges)
                                        med->flag = ME_EDGEDRAW | ME_EDGERENDER;
                                med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
                                med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
@@ -904,7 +1010,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
                                        MEdge *med;
 
                                        med = &medge[i];
-                                       if(ccgdm->drawInteriorEdges)
+                                       if(cgdm->drawInteriorEdges)
                                                med->flag = ME_EDGEDRAW | ME_EDGERENDER;
                                        med->v1 = getFaceIndex(ss, f, S, x, y,
                                                                                   edgeSize, gridSize);
@@ -913,7 +1019,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
                                        i++;
 
                                        med = &medge[i];
-                                       if(ccgdm->drawInteriorEdges)
+                                       if(cgdm->drawInteriorEdges)
                                                med->flag = ME_EDGEDRAW | ME_EDGERENDER;
                                        med->v1 = getFaceIndex(ss, f, S, y, x,
                                                                                   edgeSize, gridSize);
@@ -927,7 +1033,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
 
        totedge = ccgSubSurf_getNumEdges(ss);
        for(index = 0; index < totedge; index++) {
-               CCGEdge *e = ccgdm->edgeMap[index].edge;
+               CCGEdge *e = cgdm->edgeMap[index].edge;
                unsigned int flags = 0;
                int x;
                int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
@@ -955,18 +1061,18 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
 
 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
 {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        int index;
        int totface;
        int gridSize = ccgSubSurf_getGridSize(ss);
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int i = 0;
-       char *faceFlags = ccgdm->faceFlags;
+       char *faceFlags = cgdm->faceFlags;
 
        totface = ccgSubSurf_getNumFaces(ss);
        for(index = 0; index < totface; index++) {
-               CCGFace *f = ccgdm->faceMap[index].face;
+               CCGFace *f = cgdm->faceMap[index].face;
                int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
                int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
                int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
@@ -983,6 +1089,11 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
                                                                                  edgeSize, gridSize);
                                        mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
                                                                                  edgeSize, gridSize);
+                                       if (faceFlags) {
+                                               mat_nr = faceFlags[index*2+1];
+                                               mf->flag = faceFlags[index*2];
+                                       } else mf->flag = flag;
+
                                        mf->mat_nr = mat_nr;
                                        mf->flag = flag;
 
@@ -993,9 +1104,118 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
        }
 }
 
-static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
+{
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
+       int index;
+       int totface;
+       int gridSize = ccgSubSurf_getGridSize(ss);
+       int edgeSize = ccgSubSurf_getEdgeSize(ss);
+       int i = 0;
+       MLoop *mv;
+       /* char *faceFlags = cgdm->faceFlags; */ /* UNUSED */
+
+       if (!cgdm->ehash) {
+               MEdge *medge;
+
+               cgdm->ehash = BLI_edgehash_new();
+               medge = cgdm->dm.getEdgeArray((DerivedMesh*)cgdm);
+
+               for (i=0; i<cgdm->dm.numEdgeData; i++) {
+                       BLI_edgehash_insert(cgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
+               }
+       }
+
+       totface = ccgSubSurf_getNumFaces(ss);
+       mv = mloop;
+       for(index = 0; index < totface; index++) {
+               CCGFace *f = cgdm->faceMap[index].face;
+               int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
+               /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */
+               /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */
+
+               for(S = 0; S < numVerts; S++) {
+                       for(y = 0; y < gridSize - 1; y++) {
+                               for(x = 0; x < gridSize - 1; x++) {
+                                       int v1, v2, v3, v4;
+
+                                       v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
+                                                                                 edgeSize, gridSize);
+
+                                       v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
+                                                                                 edgeSize, gridSize);
+                                       v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
+                                                                                 edgeSize, gridSize);
+                                       v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
+                                                                                 edgeSize, gridSize);
+
+                                       mv->v = v1;
+                                       mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v1, v2));
+                                       mv++, i++;
+
+                                       mv->v = v2;
+                                       mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v2, v3));
+                                       mv++, i++;
+
+                                       mv->v = v3;
+                                       mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v3, v4));
+                                       mv++, i++;
+
+                                       mv->v = v4;
+                                       mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v4, v1));
+                                       mv++, i++;
+                               }
+                       }
+               }
+       }
+}
+
+
+static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mface)
+{
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
+       int index;
+       int totface;
+       int gridSize = ccgSubSurf_getGridSize(ss);
+       /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
+       int i = 0, k = 0;
+       char *faceFlags = cgdm->faceFlags;
+
+       totface = ccgSubSurf_getNumFaces(ss);
+       for(index = 0; index < totface; index++) {
+               CCGFace *f = cgdm->faceMap[index].face;
+               int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
+               int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
+               int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
+
+               for(S = 0; S < numVerts; S++) {
+                       for(y = 0; y < gridSize - 1; y++) {
+                               for(x = 0; x < gridSize - 1; x++) {
+                                       MPoly *mf = &mface[i];
+
+                                       if (faceFlags) {
+                                               mat_nr = faceFlags[index*2+1];
+                                               mf->flag = faceFlags[index*2];
+                                       } else mf->flag = flag;
+
+                                       mf->mat_nr = mat_nr;
+                                       mf->flag = flag;
+                                       mf->loopstart = k;
+                                       mf->totloop = 4;
+
+                                       k += 4;
+                                       i++;
+                               }
+                       }
+               }
+       }
+}
+
+static void cgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
        int i;
@@ -1076,14 +1296,14 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
        MEM_freeN(edgeMap2);
        MEM_freeN(faceMap2);
 }
-static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
+static void cgdm_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGVertIterator *vi = ccgSubSurf_getVertIterator(cgdm->ss);
 
        for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
-               DMGridData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
-               int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
+               DMGridData *vd = ccgSubSurf_getVertData(cgdm->ss, v);
+               int index = ccgDM_getVertMapIndex(cgdm->ss, v);
 
                if (index!=-1)
                        func(userData, index, vd->co, vd->no, NULL);
@@ -1091,9 +1311,9 @@ static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData
 
        ccgVertIterator_free(vi);
 }
-static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+static void cgdm_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
@@ -1112,8 +1332,8 @@ static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData
 }
 
 static void ccgDM_drawVerts(DerivedMesh *dm) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
        CCGVertIterator *vi;
@@ -1244,8 +1464,8 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(draw
        ccgEdgeIterator_free(ei);
 }
 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
@@ -1368,21 +1588,21 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
 }
 
        /* Only used by non-editmesh types */
-static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
        GPUVertexAttribs gattribs;
        DMVertexAttribs attribs= {{{NULL}}};
-       MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
+       MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE);
        int gridSize = ccgSubSurf_getGridSize(ss);
        int gridFaces = gridSize - 1;
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int transp, orig_transp, new_transp;
-       char *faceFlags = ccgdm->faceFlags;
+       char *faceFlags = cgdm->faceFlags;
        int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
 
-       ccgdm_pbvh_update(ccgdm);
+       ccgdm_pbvh_update(cgdm);
 
        doDraw = 0;
        matnr = -1;
@@ -1412,7 +1632,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v
 
        totface = ccgSubSurf_getNumFaces(ss);
        for(a = 0, i = 0; i < totface; i++) {
-               CCGFace *f = ccgdm->faceMap[i].face;
+               CCGFace *f = cgdm->faceMap[i].face;
                int S, x, y, drawSmooth;
                int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
                int origIndex = ccgDM_getFaceMapIndex(ss, f);
@@ -1523,19 +1743,19 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v
        ccgFaceIterator_free(fi);
 }
 
-static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
+static void cgdm_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
        dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
 }
 
-static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+static void cgdm_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
        unsigned char *cp1, *cp2;
        int useTwoSide=1;
 
-       ccgdm_pbvh_update(ccgdm);
+       ccgdm_pbvh_update(cgdm);
 
        cp1= col1;
        if(col2) {
@@ -1596,27 +1816,27 @@ static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), uns
        ccgFaceIterator_free(fi);
 }
 
-static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
-       int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
+static void cgdm_drawFacesTex_common(DerivedMesh *dm,
+       int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
        int (*drawParamsMapped)(void *userData, int index),
        void *userData) 
 {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
-       MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
-       MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
-       char *faceFlags = ccgdm->faceFlags;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
+       MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
+       MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
+       char *faceFlags = cgdm->faceFlags;
        int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
        int gridFaces = gridSize - 1;
 
-       ccgdm_pbvh_update(ccgdm);
+       ccgdm_pbvh_update(cgdm);
 
        if(!mcol)
-               mcol = dm->getFaceDataArray(dm, CD_MCOL);
+               mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
 
        totface = ccgSubSurf_getNumFaces(ss);
        for(i = 0; i < totface; i++) {
-               CCGFace *f = ccgdm->faceMap[i].face;
+               CCGFace *f = cgdm->faceMap[i].face;
                int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
                int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
                int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
@@ -1633,7 +1853,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
                }
 
                if(drawParams)
-                       flag = drawParams(tf, mcol, mat_nr);
+                       flag = drawParams(tf, mcol!=NULL, mat_nr);
                else if (index != ORIGINDEX_NONE)
                        flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
                else
@@ -1736,21 +1956,21 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
        }
 }
 
-static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
+static void cgdm_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
 {
-       ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
+       cgdm_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
 }
 
-static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
+static void cgdm_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
 {
-       ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
+       cgdm_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
 }
 
-static void ccgDM_drawUVEdges(DerivedMesh *dm)
+static void cgdm_drawUVEdges(DerivedMesh *dm)
 {
 
-       MFace *mf = dm->getFaceArray(dm);
-       MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
+       MFace *mf = dm->getTessFaceArray(dm);
+       MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
        int i;
        
        if (tf) {
@@ -1781,25 +2001,25 @@ static void ccgDM_drawUVEdges(DerivedMesh *dm)
 
 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
                        int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        MCol *mcol= NULL;
        int i, gridSize = ccgSubSurf_getGridSize(ss);
-       char *faceFlags = ccgdm->faceFlags;
+       char *faceFlags = cgdm->faceFlags;
        int gridFaces = gridSize - 1, totface;
 
        /* currently unused -- each original face is handled separately */
        (void)compareDrawOptions;
 
        if(useColors) {
-               mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
+               mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
                if(!mcol)
-                       mcol = dm->getFaceDataArray(dm, CD_MCOL);
+                       mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
        }
 
        totface = ccgSubSurf_getNumFaces(ss);
        for(i = 0; i < totface; i++) {
-               CCGFace *f = ccgdm->faceMap[i].face;
+               CCGFace *f = cgdm->faceMap[i].face;
                int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
                int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
                int origIndex;
@@ -1899,9 +2119,9 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *u
                }
        }
 }
-static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+static void cgdm_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
@@ -1929,9 +2149,9 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *u
 
        ccgEdgeIterator_free(ei);
 }
-static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
@@ -1960,9 +2180,9 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(v
 
        ccgEdgeIterator_free(ei);
 }
-static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
+static void cgdm_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
+       CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = cgdm->ss;
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
 
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
@@ -1980,7 +2200,7 @@ static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *us
        ccgFaceIterator_free(fi);
 }
 
-static void ccgDM_release(DerivedMesh *dm) {
+static void cgdm_release(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 
        if (DM_release(dm)) {
@@ -1993,6 +2213,10 @@ static void ccgDM_release(DerivedMesh *dm) {
                                ccgdm->multires.update(dm);
                }
 
+               if (ccgdm->ehash)
+                       BLI_edgehash_free(ccgdm->ehash, NULL);
+
+               if(ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);
                if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
                if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
                if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
@@ -2009,12 +2233,66 @@ static void ccgDM_release(DerivedMesh *dm) {
        }
 }
 
+static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, 
+                         CustomData *pdata, int loopstart, int findex, 
+                         int polyindex, int numTex, int numCol) 
+{
+       MTFace *texface;
+       MTexPoly *texpoly;
+       MCol *mcol;
+       MLoopCol *mloopcol;
+       MLoopUV *mloopuv;
+       int i, j, hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
+
+       for(i=0; i < numTex; i++){
+               texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
+               texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
+               
+               texface->tpage = texpoly->tpage;
+               texface->flag = texpoly->flag;
+               texface->transp = texpoly->transp;
+               texface->mode = texpoly->mode;
+               texface->tile = texpoly->tile;
+               texface->unwrap = texpoly->unwrap;
+
+               mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
+               for (j=0; j<4; j++, mloopuv++) {
+                       texface->uv[j][0] = mloopuv->uv[0];
+                       texface->uv[j][1] = mloopuv->uv[1];
+               }
+       }
+
+       for(i=0; i < numCol; i++){
+               mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i);
+               mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
+
+               for (j=0; j<4; j++, mloopcol++) {
+                       mcol[j].r = mloopcol->r;
+                       mcol[j].g = mloopcol->g;
+                       mcol[j].b = mloopcol->b;
+                       mcol[j].a = mloopcol->a;
+               }
+       }
+       
+       if (hasWCol) {
+               mloopcol = CustomData_get(ldata, loopstart, CD_WEIGHT_MLOOPCOL);
+               mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
+
+               for (j=0; j<4; j++, mloopcol++) {
+                       mcol[j].r = mloopcol->r;
+                       mcol[j].g = mloopcol->g;
+                       mcol[j].b = mloopcol->b;
+                       mcol[j].a = mloopcol->a;
+               }
+       }
+}
+
 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
 {
        if(type == CD_ORIGINDEX) {
                /* create origindex on demand to save memory */
-               CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
-               CCGSubSurf *ss= ccgdm->ss;
+               CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
+               CCGSubSurf *ss= cgdm->ss;
                int *origindex;
                int a, index, totnone, totorig;
 
@@ -2029,8 +2307,8 @@ static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
                        origindex[a]= ORIGINDEX_NONE;
 
                for(index=0; index<totorig; index++, a++) {
-                       CCGVert *v = ccgdm->vertMap[index].vert;
-                       origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
+                       CCGVert *v = cgdm->vertMap[index].vert;
+                       origindex[a] = ccgDM_getVertMapIndex(cgdm->ss, v);
                }
 
                return origindex;
@@ -2043,8 +2321,8 @@ static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
 {
        if(type == CD_ORIGINDEX) {
                /* create origindex on demand to save memory */
-               CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
-               CCGSubSurf *ss= ccgdm->ss;
+               CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
+               CCGSubSurf *ss= cgdm->ss;
                int *origindex;
                int a, i, index, totnone, totorig, totedge;
                int edgeSize= ccgSubSurf_getEdgeSize(ss);
@@ -2061,7 +2339,7 @@ static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
                        origindex[a]= ORIGINDEX_NONE;
 
                for(index=0; index<totedge; index++) {
-                       CCGEdge *e= ccgdm->edgeMap[index].edge;
+                       CCGEdge *e= cgdm->edgeMap[index].edge;
                        int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
 
                        for(i = 0; i < edgeSize - 1; i++, a++)
@@ -2078,19 +2356,19 @@ static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
 {
        if(type == CD_ORIGINDEX) {
                /* create origindex on demand to save memory */
-               CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
-               CCGSubSurf *ss= ccgdm->ss;
+               CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
+               CCGSubSurf *ss= cgdm->ss;
                int *origindex;
                int a, i, index, totface;
                int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
 
                DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
-               origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
+               origindex= DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
 
                totface= ccgSubSurf_getNumFaces(ss);
 
                for(a=0, index=0; index<totface; index++) {
-                       CCGFace *f = ccgdm->faceMap[index].face;
+                       CCGFace *f = cgdm->faceMap[index].face;
                        int numVerts = ccgSubSurf_getFaceNumVerts(f);
                        int mapIndex = ccgDM_getFaceMapIndex(ss, f);
 
@@ -2101,19 +2379,19 @@ static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
                return origindex;
        }
 
-       return DM_get_face_data_layer(dm, type);
+       return DM_get_tessface_data_layer(dm, type);
 }
 
 static int ccgDM_getNumGrids(DerivedMesh *dm)
 {
-       CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
+       CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
        int index, numFaces, numGrids;
 
-       numFaces= ccgSubSurf_getNumFaces(ccgdm->ss);
+       numFaces= ccgSubSurf_getNumFaces(cgdm->ss);
        numGrids= 0;
 
        for(index=0; index<numFaces; index++) {
-               CCGFace *f = ccgdm->faceMap[index].face;
+               CCGFace *f = cgdm->faceMap[index].face;
                numGrids += ccgSubSurf_getFaceNumVerts(f);
        }
 
@@ -2122,11 +2400,11 @@ static int ccgDM_getNumGrids(DerivedMesh *dm)
 
 static int ccgDM_getGridSize(DerivedMesh *dm)
 {
-       CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
-       return ccgSubSurf_getGridSize(ccgdm->ss);
+       CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
+       return ccgSubSurf_getGridSize(cgdm->ss);
 }
 
-static int ccgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
+static int cgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
 {
        CCGFace *adjf;
        CCGEdge *e;
@@ -2159,15 +2437,15 @@ static int ccgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int
 
 static void ccgdm_create_grids(DerivedMesh *dm)
 {
-       CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
-       CCGSubSurf *ss= ccgdm->ss;
+       CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
+       CCGSubSurf *ss= cgdm->ss;
        DMGridData **gridData;
        DMGridAdjacency *gridAdjacency, *adj;
        CCGFace **gridFaces;
        int *gridOffset;
        int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
 
-       if(ccgdm->gridData)
+       if(cgdm->gridData)
                return;
        
        numGrids = ccgDM_getNumGrids(dm);
@@ -2175,10 +2453,10 @@ static void ccgdm_create_grids(DerivedMesh *dm)
        /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
 
        /* compute offset into grid array for each face */
-       gridOffset = MEM_mallocN(sizeof(int)*numFaces, "ccgdm.gridOffset");
+       gridOffset = MEM_mallocN(sizeof(int)*numFaces, "cgdm.gridOffset");
 
        for(gIndex = 0, index = 0; index < numFaces; index++) {
-               CCGFace *f = ccgdm->faceMap[index].face;
+               CCGFace *f = cgdm->faceMap[index].face;
                int numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                gridOffset[index] = gIndex;
@@ -2186,12 +2464,12 @@ static void ccgdm_create_grids(DerivedMesh *dm)
        }
 
        /* compute grid data */
-       gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData");
-       gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency");
-       gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces");
+       gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "cgdm.gridData");
+       gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "cgdm.gridAdjacency");
+       gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "cgdm.gridFaces");
 
        for(gIndex = 0, index = 0; index < numFaces; index++) {
-               CCGFace *f = ccgdm->faceMap[index].face;
+               CCGFace *f = cgdm->faceMap[index].face;
                int numVerts = ccgSubSurf_getFaceNumVerts(f);
 
                for(S = 0; S < numVerts; S++, gIndex++) {
@@ -2205,43 +2483,43 @@ static void ccgdm_create_grids(DerivedMesh *dm)
 
                        adj->index[0] = gIndex - S + nextS;
                        adj->rotation[0] = 3;
-                       adj->index[1] = ccgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
+                       adj->index[1] = cgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
                        adj->rotation[1] = 1;
-                       adj->index[2] = ccgdm_adjacent_grid(ss, gridOffset, f, S, 1);
+                       adj->index[2] = cgdm_adjacent_grid(ss, gridOffset, f, S, 1);
                        adj->rotation[2] = 3;
                        adj->index[3] = gIndex - S + prevS;
                        adj->rotation[3] = 1;
                }
        }
 
-       ccgdm->gridData = gridData;
-       ccgdm->gridFaces = gridFaces;
-       ccgdm->gridAdjacency = gridAdjacency;
-       ccgdm->gridOffset = gridOffset;
+       cgdm->gridData = gridData;
+       cgdm->gridFaces = gridFaces;
+       cgdm->gridAdjacency = gridAdjacency;
+       cgdm->gridOffset = gridOffset;
 }
 
 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
 {
-       CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
+       CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
 
        ccgdm_create_grids(dm);
-       return ccgdm->gridData;
+       return cgdm->gridData;
 }
 
 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
 {
-       CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
+       CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
 
        ccgdm_create_grids(dm);
-       return ccgdm->gridAdjacency;
+       return cgdm->gridAdjacency;
 }
 
 static int *ccgDM_getGridOffset(DerivedMesh *dm)
 {
-       CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
+       CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
 
        ccgdm_create_grids(dm);
-       return ccgdm->gridOffset;
+       return cgdm->gridOffset;
 }
 
 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
@@ -2328,50 +2606,74 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                                                                                 int useSubsurfUv,
                                                                                 DerivedMesh *dm)
 {
-       CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
+       CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "cgdm");
        CCGVertIterator *vi;
        CCGEdgeIterator *ei;
        CCGFaceIterator *fi;
        int index, totvert, totedge, totface;
        int i;
        int vertNum, edgeNum, faceNum;
+       int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex; /* *edgeOrigIndex - as yet, unused  */
        short *edgeFlags;
        char *faceFlags;
-       int edgeSize;
+       int *loopidx = NULL, *vertidx = NULL;
+       BLI_array_declare(loopidx);
+       BLI_array_declare(vertidx);
+       int loopindex, loopindex2;
+       int edgeSize, has_edge_origindex;
        int gridSize;
-       int gridFaces;
+       int gridFaces, gridCuts;
        /*int gridSideVerts;*/
        int gridSideEdges;
+       int numTex, numCol;
        int gridInternalEdges;
+       float *w = NULL;
+       WeightTable wtable = {0};
+       MCol *mcol;
        MEdge *medge = NULL;
-       MFace *mface = NULL;
-       int *orig_indices;
-       FaceVertWeight *qweight, *tweight;
+       /* MFace *mface = NULL; */
+       MPoly *mpoly = NULL;
 
        DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
                                         ccgSubSurf_getNumFinalVerts(ss),
                                         ccgSubSurf_getNumFinalEdges(ss),
+                                        ccgSubSurf_getNumFinalFaces(ss),
+                                        ccgSubSurf_getNumFinalFaces(ss)*4, 
                                         ccgSubSurf_getNumFinalFaces(ss));
+       
+       numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
+       numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
+       
+       if (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex)
+               CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
+       else if (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol)
+               CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
 
-       ccgdm->dm.getMinMax = ccgDM_getMinMax;
-       ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
-       ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
+       ccgdm->dm.getMinMax = cgdm_getMinMax;
+       ccgdm->dm.getNumVerts = cgdm_getNumVerts;
+       ccgdm->dm.getNumEdges = cgdm_getNumEdges;
+       ccgdm->dm.getNumTessFaces = cgdm_getNumTessFaces;
+       ccgdm->dm.getNumFaces = cgdm_getNumTessFaces;
+
+       ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
+       ccgdm->dm.getPBVH = ccgDM_getPBVH;
 
-       ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
        ccgdm->dm.getVert = ccgDM_getFinalVert;
        ccgdm->dm.getEdge = ccgDM_getFinalEdge;
-       ccgdm->dm.getFace = ccgDM_getFinalFace;
+       ccgdm->dm.getTessFace = ccgDM_getFinalFace;
        ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
        ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
        ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
        ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
-       ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
+       ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
+       ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
+       ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
        ccgdm->dm.getVertData = DM_get_vert_data;
        ccgdm->dm.getEdgeData = DM_get_edge_data;
-       ccgdm->dm.getFaceData = DM_get_face_data;
+       ccgdm->dm.getTessFaceData = DM_get_face_data;
        ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
        ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
-       ccgdm->dm.getFaceDataArray = ccgDM_get_face_data_layer;
+       ccgdm->dm.getTessFaceDataArray = ccgDM_get_face_data_layer;
        ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
        ccgdm->dm.getGridSize = ccgDM_getGridSize;
        ccgdm->dm.getGridData = ccgDM_getGridData;
@@ -2380,34 +2682,45 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
        ccgdm->dm.getPBVH = ccgDM_getPBVH;
 
-       ccgdm->dm.getVertCos = ccgdm_getVertCos;
-       ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
-       ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
-       ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
+       ccgdm->dm.getTessFace = ccgDM_getFinalFace;
+       ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
+       ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
+       ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
+       ccgdm->dm.getVertData = DM_get_vert_data;
+       ccgdm->dm.getEdgeData = DM_get_edge_data;
+       ccgdm->dm.getTessFaceData = DM_get_face_data;
+       ccgdm->dm.getVertDataArray = DM_get_vert_data_layer;
+       ccgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
+       ccgdm->dm.getTessFaceDataArray = DM_get_tessface_data_layer;
+
+       ccgdm->dm.getVertCos = cgdm_getVertCos;
+       ccgdm->dm.foreachMappedVert = cgdm_foreachMappedVert;
+       ccgdm->dm.foreachMappedEdge = cgdm_foreachMappedEdge;
+       ccgdm->dm.foreachMappedFaceCenter = cgdm_foreachMappedFaceCenter;
        
        ccgdm->dm.drawVerts = ccgDM_drawVerts;
        ccgdm->dm.drawEdges = ccgDM_drawEdges;
        ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
        ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
-       ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
-       ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
-       ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
+       ccgdm->dm.drawFacesColored = cgdm_drawFacesColored;
+       ccgdm->dm.drawFacesTex = cgdm_drawFacesTex;
+       ccgdm->dm.drawFacesGLSL = cgdm_drawFacesGLSL;
        ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
-       ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
-       ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
-       ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
+       ccgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex;
+       ccgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL;
+       ccgdm->dm.drawUVEdges = cgdm_drawUVEdges;
 
-       ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
-       ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
+       ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;
+       ccgdm->dm.drawMappedEdges = cgdm_drawMappedEdges;
        
-       ccgdm->dm.release = ccgDM_release;
+       ccgdm->dm.release = cgdm_release;
        
        ccgdm->ss = ss;
        ccgdm->drawInteriorEdges = drawInteriorEdges;
        ccgdm->useSubsurfUv = useSubsurfUv;
 
        totvert = ccgSubSurf_getNumVerts(ss);
-       ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
+       ccgdm->vertMap = MEM_callocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
        vi = ccgSubSurf_getVertIterator(ss);
        for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
@@ -2417,7 +2730,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        ccgVertIterator_free(vi);
 
        totedge = ccgSubSurf_getNumEdges(ss);
-       ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
+       ccgdm->edgeMap = MEM_callocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
        ei = ccgSubSurf_getEdgeIterator(ss);
        for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -2426,7 +2739,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        }
 
        totface = ccgSubSurf_getNumFaces(ss);
-       ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
+       ccgdm->faceMap = MEM_callocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
        fi = ccgSubSurf_getFaceIterator(ss);
        for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
@@ -2435,139 +2748,190 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        }
        ccgFaceIterator_free(fi);
 
+       ccgdm->reverseFaceMap = MEM_callocN(sizeof(int)*ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap");
+
        edgeSize = ccgSubSurf_getEdgeSize(ss);
        gridSize = ccgSubSurf_getGridSize(ss);
        gridFaces = gridSize - 1;
-       /*gridSideVerts = gridSize - 2;*/ /*UNUSED*/
-       /*gridInternalVerts = gridSideVerts * gridSideVerts; */ /*UNUSED*/
+       gridCuts = gridSize - 2;
+       /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
        gridSideEdges = gridSize - 1;
        gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
 
-       calc_ss_weights(gridFaces, &qweight, &tweight);
-
        vertNum = 0;
        edgeNum = 0;
        faceNum = 0;
 
-       /* mvert = dm->getVertArray(dm); - as yet unused */
+       /* mvert = dm->getVertArray(dm); */ /* UNUSED */
        medge = dm->getEdgeArray(dm);
-       mface = dm->getFaceArray(dm);
+       /* mface = dm->getTessFaceArray(dm); */ /* UNUSED */
 
+       mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
+       base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
+       
+       /*CDDM hack*/
+       edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "faceFlags");
        faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
 
-       orig_indices = (int*)ccgdm->dm.getFaceDataArray(&ccgdm->dm, CD_ORIGINDEX);
-       for(index = 0; index < totface; ++index) {
+       vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
+       /*edgeOrigIndex = DM_get_edge_data_layer(&cgdm->dm, CD_ORIGINDEX);*/
+       faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
+
+       polyOrigIndex = DM_get_face_data_layer(&ccgdm->dm, CD_ORIGINDEX);
+
+       if (!CustomData_has_layer(&ccgdm->dm.faceData, CD_MCOL))
+               DM_add_tessface_layer(&ccgdm->dm, CD_MCOL, CD_CALLOC, NULL);
+
+       mcol = DM_get_tessface_data_layer(&ccgdm->dm, CD_MCOL);
+       has_edge_origindex = CustomData_has_layer(&ccgdm->dm.edgeData, CD_ORIGINDEX);
+
+       faceNum = 0;
+       loopindex = loopindex2 = 0; //current loop index
+       for (index = 0; index < totface; index++) {
                CCGFace *f = ccgdm->faceMap[index].face;
                int numVerts = ccgSubSurf_getFaceNumVerts(f);
                int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
                int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
-               FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
-               int S, x, y;
-               int vertIdx[4];
+               int g2_wid = gridCuts+2;
+               float *w2;
+               int s, x, y;
+               
+               origIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
+               
+               w = get_ss_weights(&wtable, gridCuts, numVerts);
 
                ccgdm->faceMap[index].startVert = vertNum;
                ccgdm->faceMap[index].startEdge = edgeNum;
                ccgdm->faceMap[index].startFace = faceNum;
-
-               if(orig_indices)
-                       orig_indices[faceNum] = origIndex;
+               
+               faceFlags[0] = mpoly ?  mpoly[origIndex].flag : 0;
+               faceFlags[1] = mpoly ? mpoly[origIndex].mat_nr : 0;
+               faceFlags += 2;
 
                /* set the face base vert */
                *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
 
-               for(S = 0; S < numVerts; S++) {
-                       CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
+               BLI_array_empty(loopidx);               
+               for (s=0; s<numVerts; s++) {
+                       BLI_array_growone(loopidx);
+                       loopidx[s] = loopindex++;
+               }
+               
+               BLI_array_empty(vertidx);
+                               for(s = 0; s < numVerts; s++) {
+                       CCGVert *v = ccgSubSurf_getFaceVert(ss, f, s);
+                       
+                       BLI_array_growone(vertidx);
+                       vertidx[s] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
+               }
+               
 
-                       vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
+               /*I think this is for interpolating the center vert?*/
+               w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1);
+               DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
+                                   numVerts, vertNum);
+               if (vertOrigIndex) {
+                       *vertOrigIndex = ORIGINDEX_NONE;
+                       ++vertOrigIndex;
                }
 
-               DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
-                                                       numVerts, vertNum);
                ++vertNum;
 
-               for(S = 0; S < numVerts; S++) {
-                       int prevS = (S - 1 + numVerts) % numVerts;
-                       int nextS = (S + 1) % numVerts;
-                       int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
+               /*interpolate per-vert data*/
+               for(s = 0; s < numVerts; s++) {
                        for(x = 1; x < gridFaces; x++) {
-                               float w[4];
-                               w[prevS]  = weight[x][0][0];
-                               w[S]      = weight[x][0][1];
-                               w[nextS]  = weight[x][0][2];
-                               w[otherS] = weight[x][0][3];
-                               DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
-                                                                       numVerts, vertNum);
+                               w2 = w + s*numVerts*g2_wid*g2_wid + x*numVerts;
+                               DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
+                                                   numVerts, vertNum);
+
+                               if (vertOrigIndex) {
+                                       *vertOrigIndex = ORIGINDEX_NONE;
+                                       ++vertOrigIndex;
+                               }
+
                                ++vertNum;
                        }
                }
 
-               for(S = 0; S < numVerts; S++) {
-                       int prevS = (S - 1 + numVerts) % numVerts;
-                       int nextS = (S + 1) % numVerts;
-                       int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
+               /*interpolate per-vert data*/
+               for(s = 0; s < numVerts; s++) {
                        for(y = 1; y < gridFaces; y++) {
                                for(x = 1; x < gridFaces; x++) {
-                                       float w[4];
-                                       w[prevS]  = weight[y * gridFaces + x][0][0];
-                                       w[S]      = weight[y * gridFaces + x][0][1];
-                                       w[nextS]  = weight[y * gridFaces + x][0][2];
-                                       w[otherS] = weight[y * gridFaces + x][0][3];
-                                       DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
-                                                                               numVerts, vertNum);
+                                       w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
+                                       DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
+                                                           numVerts, vertNum);
+
+                                       if (vertOrigIndex) {
+                                               *vertOrigIndex = ORIGINDEX_NONE;
+                                               ++vertOrigIndex;
+                                       }
+
                                        ++vertNum;
                                }
                        }
                }
 
-               for(S = 0; S < numVerts; S++) {
-                       int prevS = (S - 1 + numVerts) % numVerts;
-                       int nextS = (S + 1) % numVerts;
-                       int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
-
-                       weight = (numVerts == 4) ? qweight : tweight;
-
-                       for(y = 0; y < gridFaces; y++) {
-                               for(x = 0; x < gridFaces; x++) {
-                                       FaceVertWeight w;
-                                       int j;
-
-                                       for(j = 0; j < 4; ++j) {
-                                               w[j][prevS]  = (*weight)[j][0];
-                                               w[j][S]      = (*weight)[j][1];
-                                               w[j][nextS]  = (*weight)[j][2];
-                                               w[j][otherS] = (*weight)[j][3];
+               if (has_edge_origindex) {
+                       for(i = 0; i < numFinalEdges; ++i)
+                               *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
+                                                        CD_ORIGINDEX) = ORIGINDEX_NONE;
+               }
+
+               for (s=0; s<numVerts; s++) {
+                       /*interpolate per-face data*/
+                       for (y=0; y<gridFaces; y++) {
+                               for (x=0; x<gridFaces; x++) {
+                                       w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
+                                       CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
+                                                         loopidx, w2, NULL, numVerts, loopindex2);
+                                       loopindex2++;
+
+                                       w2 = w + s*numVerts*g2_wid*g2_wid + ((y+1)*g2_wid+(x))*numVerts;
+                                       CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
+                                                         loopidx, w2, NULL, numVerts, loopindex2);
+                                       loopindex2++;
+
+                                       w2 = w + s*numVerts*g2_wid*g2_wid + ((y+1)*g2_wid+(x+1))*numVerts;
+                                       CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
+                                                         loopidx, w2, NULL, numVerts, loopindex2);
+                                       loopindex2++;
+                                       
+                                       w2 = w + s*numVerts*g2_wid*g2_wid + ((y)*g2_wid+(x+1))*numVerts;
+                                       CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
+                                                         loopidx, w2, NULL, numVerts, loopindex2);
+                                       loopindex2++;
+
+                                       /*copy over poly data, e.g. mtexpoly*/
+                                       CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
+
+                                       /*generate tesselated face data used for drawing*/
+                                       ccg_loops_to_corners(&ccgdm->dm.faceData, &ccgdm->dm.loopData,
+                                               &ccgdm->dm.polyData, loopindex2-4, faceNum, faceNum, numTex, numCol);
+                                       
+                                       /*set original index data*/
+                                       if (faceOrigIndex) {
+                                               *faceOrigIndex = origIndex;
+                                               faceOrigIndex++;
+                                       }
+                                       if (polyOrigIndex) {
+                                               *polyOrigIndex = origIndex;
+                                               polyOrigIndex++;
                                        }
 
-                                       DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
-                                                                               &w, 1, faceNum);
-                                       weight++;
+                                       ccgdm->reverseFaceMap[faceNum] = index;
 
-                                       ++faceNum;
+                                       faceNum++;
                                }
                        }
                }
 
-               faceFlags[index*2] = mface[origIndex].flag;
-               faceFlags[index*2 + 1] = mface[origIndex].mat_nr;
-
                edgeNum += numFinalEdges;
        }
 
-       if(useSubsurfUv) {
-               CustomData *fdata = &ccgdm->dm.faceData;
-               CustomData *dmfdata = &dm->faceData;
-               int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
-               int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
-
-               for (i=0; i<numlayer && i<dmnumlayer; i++)
-                       set_subsurf_uv(ss, dm, &ccgdm->dm, i);
-       }
-
-       edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "edgeFlags");
-
        for(index = 0; index < totedge; ++index) {
                CCGEdge *e = ccgdm->edgeMap[index].edge;
                int numFinalEdges = edgeSize - 1;
+               int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
                int x;
                int vertIdx[2];
                int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
@@ -2581,6 +2945,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                ccgdm->edgeMap[index].startVert = vertNum;
                ccgdm->edgeMap[index].startEdge = edgeNum;
 
+               if(edgeIdx >= 0 && edgeFlags)
+                       edgeFlags[edgeIdx] = medge[edgeIdx].flag;
+
                /* set the edge base vert */
                *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
 
@@ -2589,32 +2956,53 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                        w[1] = (float) x / (edgeSize - 1);
                        w[0] = 1 - w[1];
                        DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
+                       if (vertOrigIndex) {
+                               *vertOrigIndex = ORIGINDEX_NONE;
+                               ++vertOrigIndex;
+                       }
                        ++vertNum;
                }
 
-               edgeFlags[index]= medge[edgeIdx].flag;
+               for(i = 0; i < numFinalEdges; ++i) {
+                       if (has_edge_origindex) {
+                               *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
+                                                CD_ORIGINDEX) = mapIndex;
+                       }
+               }
 
                edgeNum += numFinalEdges;
        }
 
        for(index = 0; index < totvert; ++index) {
                CCGVert *v = ccgdm->vertMap[index].vert;
-               int vertIdx;
+               int mapIndex = ccgDM_getVertMapIndex(ccgdm->ss, v);
+               int vidx;
 
-               vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
+               vidx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
 
                ccgdm->vertMap[index].startVert = vertNum;
 
                /* set the vert base vert */
                *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
 
-               DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
+               DM_copy_vert_data(dm, &ccgdm->dm, vidx, vertNum, 1);
 
+               if (vertOrigIndex) {
+                       *vertOrigIndex = mapIndex;
+                       ++vertOrigIndex;
+               }
                ++vertNum;
        }
 
-       MEM_freeN(qweight);
-       MEM_freeN(tweight);
+       ccgdm->dm.numVertData = vertNum;
+       ccgdm->dm.numEdgeData = edgeNum;
+       ccgdm->dm.numFaceData = faceNum;
+       ccgdm->dm.numLoopData = loopindex2;
+       ccgdm->dm.numPolyData = faceNum;
+
+       BLI_array_free(vertidx);
+       BLI_array_free(loopidx);
+       free_ss_weights(&wtable);
 
        return ccgdm;
 }
@@ -2631,7 +3019,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
        int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
        int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
        int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
-       CCGDerivedMesh *result;
+       CCGDerivedMesh *result = NULL;
 
        if(forEditMode) {
                int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
@@ -2660,7 +3048,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
 
                result->freeSS = 1;
        } else {
-               int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
+               int useIncremental = 1; //(smd->flags & eSubsurfModifierFlag_Incremental);
                int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
                int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
                CCGSubSurf *ss;
@@ -2685,7 +3073,14 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
                        smd->mCache = ss = _getSubSurf(smd->mCache, levels,
                                                                                   useAging, 0, useSimple);
 
-                       ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
+                       if (!ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple)) {
+                               //ccgSubSurf_free(smd->mCache);
+                               smd->mCache = ss = _getSubSurf(NULL, levels,
+                                                                                          useAging, 0, useSimple);
+                               
+                               ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
+       
+                       }
 
                        result = getCCGDerivedMesh(smd->mCache,
                                                                           drawInteriorEdges,
@@ -2707,8 +3102,8 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
                                result->freeSS = 1;
                }
        }
-
-       return (DerivedMesh*)result;
+       
+       return (DerivedMesh *)result;
 }
 
 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])