diff options
Diffstat (limited to 'source/blender/blenkernel/intern/subsurf_ccg.c')
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 1188 |
1 files changed, 810 insertions, 378 deletions
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 050aaee92e4..1d1a10f57e3 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -44,12 +44,12 @@ #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" @@ -58,6 +58,10 @@ #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" @@ -69,9 +73,10 @@ 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); /// @@ -159,7 +164,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); @@ -196,13 +202,12 @@ static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edg } } -static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) { - unsigned int *fv = &mf->v1; +static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mp, struct MLoop *ml, int fi, CCGVertHDL *fverts) { UvMapVert *v, *nv; - int j, nverts= mf->v4? 4: 3; + int j, nverts= mp->totloop; - for (j=0; j<nverts; j++, fv++) { - for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) { + for (j=0; j<nverts; j++) { + for (nv=v=get_uv_map_vert(vmap, ml[j].v); v; v=v->next) { if (v->separate) nv= v; if (v->f == fi) @@ -213,8 +218,9 @@ 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); +static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MLoopUV *mloopuv) { + MPoly *mpoly = dm->getPolyArray(dm); + MLoop *mloop = dm->getLoopArray(dm); MVert *mvert = dm->getVertArray(dm); int totvert = dm->getNumVerts(dm); int totface = dm->getNumFaces(dm); @@ -222,12 +228,13 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, UvMapVert *v; UvVertMap *vmap; float limit[2]; - CCGVertHDL fverts[4]; + CCGVertHDL *fverts= NULL; + BLI_array_declare(fverts); EdgeHash *ehash; float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss); limit[0]= limit[1]= STD_UV_CONNECT_LIMIT; - vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit); + vmap= make_uv_vert_map(mpoly, mloop, mloopuv, totface, totvert, 0, limit); if (!vmap) return 0; @@ -250,8 +257,8 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex); float uv[3]; - uv[0]= (tface+v->f)->uv[v->tfindex][0]; - uv[1]= (tface+v->f)->uv[v->tfindex][1]; + uv[0]= mloopuv[mpoly[v->f].loopstart + v->tfindex].uv[0]; + uv[1]= mloopuv[mpoly[v->f].loopstart + v->tfindex].uv[1]; uv[2]= 0.0f; ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv); @@ -263,18 +270,22 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, ehash = BLI_edgehash_new(); for (i=0; i<totface; i++) { - MFace *mf = &((MFace*) mface)[i]; - int nverts= mf->v4? 4: 3; + MPoly *mp = &((MPoly*) mpoly)[i]; + int nverts= mp->totloop; CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i)); - unsigned int *fv = &mf->v1; + /* unsigned int *fv = &mp->v1; */ + MLoop *ml= mloop + mp->loopstart; - get_face_uv_map_vert(vmap, mf, i, fverts); + BLI_array_empty(fverts); + BLI_array_growitems(fverts, nverts); + + get_face_uv_map_vert(vmap, mp, ml, i, fverts); for (j=0; j<nverts; j++) { int v0 = GET_INT_FROM_POINTER(fverts[j]); int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]); - MVert *mv0 = mvert + *(fv+j); - MVert *mv1 = mvert + *(fv+((j+1)%nverts)); + MVert *mv0 = mvert + (ml[ j ]. v); + MVert *mv1 = mvert + (ml[ ((j+1)%nverts) ].v); if (!BLI_edgehash_haskey(ehash, v0, v1)) { CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j); @@ -296,14 +307,20 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, /* create faces */ for (i=0; i<totface; i++) { - MFace *mf = &((MFace*) mface)[i]; - int nverts= mf->v4? 4: 3; + MPoly *mp = &((MPoly*) mpoly)[i]; + MLoop *ml= mloop + mp->loopstart; + int nverts= mp->totloop; CCGFace *f; - get_face_uv_map_vert(vmap, mf, i, fverts); + BLI_array_empty(fverts); + BLI_array_growitems(fverts, nverts); + + get_face_uv_map_vert(vmap, mp, ml, i, fverts); ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f); } + BLI_array_free(fverts); + free_uv_vert_map(vmap); ccgSubSurf_processSync(ss); @@ -315,18 +332,22 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, CCGSubSurf *uvss; CCGFace **faceMap; MTFace *tf; + MLoopUV *mluv; CCGFaceIterator *fi; int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S; - MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n); + MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n); + /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with + * just tface except applying the modifier then looses subsurf UV */ MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n); + MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n); - if(!dmtface || !tface) + if(!dmloopuv || (!tface && !mloopuv)) return; /* create a CCGSubSurf from uv's */ uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0); - if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) { + if(!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) { ccgSubSurf_free(uvss); return; } @@ -349,6 +370,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, /* load coordinates from uvss into tface */ tf= tface; + mluv= mloopuv; for(index = 0; index < totface; index++) { CCGFace *f = faceMap[index]; @@ -364,12 +386,22 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, float *c = faceGridData[(y + 1)*gridSize + x + 1].co; float *d = faceGridData[(y + 1)*gridSize + x + 0].co; - tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1]; - tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1]; - tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1]; - tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1]; + if (tface) { + tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1]; + tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1]; + tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1]; + tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1]; + } + + if (mloopuv) { + mluv[0].uv[0] = a[0]; mluv[0].uv[1] = a[1]; + mluv[1].uv[0] = d[0]; mluv[1].uv[1] = d[1]; + mluv[2].uv[0] = c[0]; mluv[2].uv[1] = c[1]; + mluv[3].uv[0] = b[0]; mluv[3].uv[1] = b[1]; + } tf++; + mluv+=4; } } } @@ -380,65 +412,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); } -static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, +#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 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); @@ -471,38 +561,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_poly_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; } /***/ @@ -519,9 +614,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); @@ -563,32 +658,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; @@ -601,10 +696,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; @@ -613,7 +708,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); @@ -635,28 +730,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); @@ -681,13 +776,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; @@ -697,18 +792,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); @@ -736,18 +861,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; @@ -760,8 +885,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; @@ -772,19 +897,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; @@ -804,8 +929,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; @@ -815,7 +940,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); @@ -844,7 +969,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++) { @@ -861,7 +986,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); @@ -872,25 +997,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); @@ -902,7 +1027,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); @@ -911,7 +1036,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); @@ -925,7 +1050,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)); @@ -953,18 +1078,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); /* keep types in sync with MFace, avoid many conversions */ char flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; @@ -982,6 +1107,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; @@ -992,9 +1122,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; @@ -1075,14 +1314,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); @@ -1090,9 +1329,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); @@ -1111,8 +1350,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; @@ -1240,13 +1479,13 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(draw } } static void ccgDM_drawLooseEdges(DerivedMesh *dm) { - CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - CCGSubSurf *ss = ccgdm->ss; + CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; + CCGSubSurf *ss = cgdm->ss; int totedge = ccgSubSurf_getNumEdges(ss); int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss); for (j=0; j< totedge; j++) { - CCGEdge *e = ccgdm->edgeMap[j].edge; + CCGEdge *e = cgdm->edgeMap[j].edge; DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); if (!ccgSubSurf_getEdgeNumFaces(e)) { @@ -1368,19 +1607,19 @@ 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; GPUVertexAttribs gattribs; DMVertexAttribs attribs= {{{NULL}}}; - /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ + /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ int gridSize = ccgSubSurf_getGridSize(ss); int gridFaces = gridSize - 1; int edgeSize = ccgSubSurf_getEdgeSize(ss); - 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; @@ -1408,7 +1647,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); @@ -1505,12 +1744,12 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v #undef PASSATTRIB } -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); } /* Only used by non-editmesh types */ -static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData) { +static void cgdm_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; GPUVertexAttribs gattribs; @@ -1655,14 +1894,14 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void * } -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; int gridSize = ccgSubSurf_getGridSize(ss); unsigned char *cp1, *cp2; int useTwoSide=1, i, totface; - ccgdm_pbvh_update(ccgdm); + ccgdm_pbvh_update(cgdm); cp1= col1; if(col2) { @@ -1681,7 +1920,7 @@ static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), uns glBegin(GL_QUADS); 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); for (S=0; S<numVerts; S++) { @@ -1722,30 +1961,30 @@ static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), uns glEnd(); } -static void ccgDM_drawFacesTex_common(DerivedMesh *dm, +static void cgdm_drawFacesTex_common(DerivedMesh *dm, int (*drawParams)(MTFace *tface, int has_mcol, 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); if(!mcol) - mcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL); + mcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_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)); @@ -1865,21 +2104,21 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, } } -static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_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) { @@ -1910,25 +2149,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; @@ -2030,9 +2269,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); @@ -2060,9 +2299,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); @@ -2091,9 +2330,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)) { @@ -2111,7 +2350,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)) { @@ -2124,6 +2363,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); @@ -2140,12 +2383,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; @@ -2160,8 +2457,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; @@ -2174,8 +2471,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); @@ -2192,7 +2489,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++) @@ -2209,19 +2506,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); + DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + 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); @@ -2232,19 +2529,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); } @@ -2253,11 +2550,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; @@ -2290,15 +2587,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); @@ -2306,10 +2603,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; @@ -2317,12 +2614,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++) { @@ -2336,43 +2633,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) @@ -2454,55 +2751,86 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) return ccgdm->pbvh; } +static void ccgDM_recalcTesselection(DerivedMesh *UNUSED(dm)) +{ + /* Nothing to do: CCG handles creating its own tessfaces */ +} + +static void ccgDM_calcNormals(DerivedMesh *UNUSED(dm)) +{ + /* Nothing to do: CCG calculates normals during drawing */ +} + static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int drawInteriorEdges, 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; */ /* UNUSED */ 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.getVertData = DM_get_vert_data; - ccgdm->dm.getEdgeData = DM_get_edge_data; - ccgdm->dm.getFaceData = DM_get_face_data; + ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray; + ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray; + ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray; 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; @@ -2511,35 +2839,43 @@ 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.calcNormals = ccgDM_calcNormals; + ccgdm->dm.recalcTesselation = ccgDM_recalcTesselection; + + 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.drawMappedFacesMat = ccgDM_drawMappedFacesMat; - ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges; + ccgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex; + ccgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL; + ccgdm->dm.drawMappedFacesMat = cgdm_drawMappedFacesMat; + ccgdm->dm.drawUVEdges = cgdm_drawUVEdges; - ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp; - ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges; - - ccgdm->dm.release = ccgDM_release; + ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp; + ccgdm->dm.drawMappedEdges = cgdm_drawMappedEdges; + + 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); @@ -2549,7 +2885,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); @@ -2558,7 +2894,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); @@ -2567,139 +2903,194 @@ 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_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX); + +#if 0 + /* this is not in trunk, can gives problems because colors initialize + * as black, just dont do it!, it works fine - campbell */ + 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); +#endif + + 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)); @@ -2713,6 +3104,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; @@ -2721,32 +3115,63 @@ 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; } + if(useSubsurfUv) { + CustomData *ldata = &ccgdm->dm.loopData; + CustomData *dmldata = &dm->loopData; + int numlayer = CustomData_number_of_layers(ldata, CD_MLOOPUV); + int dmnumlayer = CustomData_number_of_layers(dmldata, CD_MLOOPUV); + + for (i=0; i<numlayer && i<dmnumlayer; i++) + set_subsurf_uv(ss, dm, &ccgdm->dm, i); + } + 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; } @@ -2763,7 +3188,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; @@ -2792,7 +3217,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; @@ -2817,7 +3242,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, |