static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, CCGSubSurf *ss) { int maxGridSize = ccg_gridsize(ss->subdivLevels); int num_face_data = (numVerts * maxGridSize + numVerts * maxGridSize * maxGridSize + 1); CCGFace *f = CCGSUBSURF_alloc(ss, sizeof(CCGFace) + sizeof(CCGVert *) * numVerts + sizeof(CCGEdge *) * numVerts + ss->meshIFC.vertDataSize * num_face_data + ss->meshIFC.faceUserSize); byte *userData; int i; f->numVerts = numVerts; f->fHDL = fHDL; f->flags = 0; for (i = 0; i < numVerts; i++) { FACE_getVerts(f)[i] = verts[i]; FACE_getEdges(f)[i] = edges[i]; _vert_addFace(verts[i], f, ss); _edge_addFace(edges[i], f, ss); } userData = ccgSubSurf_getFaceUserData(ss, f); memset(userData, 0, ss->meshIFC.faceUserSize); if (ss->useAgeCounts) *((int *) &userData[ss->faceUserAgeOffset]) = ss->currentAge; return f; }
float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level, unsigned x, unsigned y) { int factor = ccg_factor(level, gpm->level); int gridsize = ccg_gridsize(gpm->level); return gpm->data[(y * factor) * gridsize + (x * factor)]; }
int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level) { if (level < 1 || level > ss->subdivLevels) { return -1; } else { return ccg_gridsize(level); } }
int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss) { int gridSize = ccg_gridsize(ss->subdivLevels); int numFinalFaces = ss->numGrids * ((gridSize - 1) * (gridSize - 1)); #ifdef WITH_OPENSUBDIV if (ss->skip_grids) { return 0; } #endif return numFinalFaces; }
int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss) { int edgeSize = ccg_edgesize(ss->subdivLevels); int gridSize = ccg_gridsize(ss->subdivLevels); int numFinalEdges = (ss->eMap->numEntries * (edgeSize - 1) + ss->numGrids * ((gridSize - 1) + 2 * ((gridSize - 2) * (gridSize - 1)))); #ifdef WITH_OPENSUBDIV if (ss->skip_grids) { return 0; } #endif return numFinalEdges; }
/* copy other places to face grid coordinates */ CCGError ccgSubSurf_updateToFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF) { int i, S, x, gridSize, cornerIdx, subdivLevels; int vertDataSize = ss->meshIFC.vertDataSize, freeF; subdivLevels = ss->subdivLevels; lvl = (lvl) ? lvl : subdivLevels; gridSize = ccg_gridsize(lvl); cornerIdx = gridSize - 1; ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF); for (i = 0; i < numEffectedF; i++) { CCGFace *f = effectedF[i]; for (S = 0; S < f->numVerts; S++) { int prevS = (S + f->numVerts - 1) % f->numVerts; CCGEdge *e = FACE_getEdges(f)[S]; CCGEdge *prevE = FACE_getEdges(f)[prevS]; for (x = 0; x < gridSize; x++) { int eI = gridSize - 1 - x; VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss); VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss); } for (x = 1; x < gridSize - 1; x++) { VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x), ss); VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x), ss); } VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), (float *)FACE_getCenterData(f), ss); VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl), ss); } } if (freeF) MEM_freeN(effectedF); return eCCGError_None; }
int BKE_ccg_gridsize(int level) { return ccg_gridsize(level); }
void *ccgSubSurf_getFaceUserData(CCGSubSurf *ss, CCGFace *f) { int maxGridSize = ccg_gridsize(ss->subdivLevels); return FACE_getCenterData(f) + ss->meshIFC.vertDataSize * (1 + f->numVerts * maxGridSize + f->numVerts * maxGridSize * maxGridSize); }
/* stitch together face grids, averaging coordinates at edges * and vertices, for multires displacements */ CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF) { CCGVert **effectedV; CCGEdge **effectedE; int numEffectedV, numEffectedE, freeF; int i, S, x, gridSize, cornerIdx, subdivLevels, edgeSize; int vertDataSize = ss->meshIFC.vertDataSize; subdivLevels = ss->subdivLevels; lvl = (lvl) ? lvl : subdivLevels; gridSize = ccg_gridsize(lvl); edgeSize = ccg_edgesize(lvl); cornerIdx = gridSize - 1; ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF); ccgSubSurf__effectedFaceNeighbours(ss, effectedF, numEffectedF, &effectedV, &numEffectedV, &effectedE, &numEffectedE); /* zero */ for (i = 0; i < numEffectedV; i++) { CCGVert *v = effectedV[i]; if (v->numFaces) VertDataZero(VERT_getCo(v, lvl), ss); } for (i = 0; i < numEffectedE; i++) { CCGEdge *e = effectedE[i]; if (e->numFaces) for (x = 0; x < edgeSize; x++) VertDataZero(EDGE_getCo(e, lvl, x), ss); } /* add */ for (i = 0; i < numEffectedF; i++) { CCGFace *f = effectedF[i]; VertDataZero((float *)FACE_getCenterData(f), ss); for (S = 0; S < f->numVerts; S++) for (x = 0; x < gridSize; x++) VertDataZero(FACE_getIECo(f, lvl, S, x), ss); for (S = 0; S < f->numVerts; S++) { int prevS = (S + f->numVerts - 1) % f->numVerts; CCGEdge *e = FACE_getEdges(f)[S]; CCGEdge *prevE = FACE_getEdges(f)[prevS]; VertDataAdd((float *)FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0), ss); if (FACE_getVerts(f)[S]->flags & Vert_eEffected) VertDataAdd(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), ss); for (x = 1; x < gridSize - 1; x++) { VertDataAdd(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0), ss); VertDataAdd(FACE_getIECo(f, lvl, prevS, x), FACE_getIFCo(f, lvl, S, 0, x), ss); } for (x = 0; x < gridSize - 1; x++) { int eI = gridSize - 1 - x; if (FACE_getEdges(f)[S]->flags & Edge_eEffected) VertDataAdd(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x), ss); if (FACE_getEdges(f)[prevS]->flags & Edge_eEffected) if (x != 0) VertDataAdd(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx), ss); } } } /* average */ for (i = 0; i < numEffectedV; i++) { CCGVert *v = effectedV[i]; if (v->numFaces) VertDataMulN(VERT_getCo(v, lvl), 1.0f / v->numFaces, ss); } for (i = 0; i < numEffectedE; i++) { CCGEdge *e = effectedE[i]; VertDataCopy(EDGE_getCo(e, lvl, 0), VERT_getCo(e->v0, lvl), ss); VertDataCopy(EDGE_getCo(e, lvl, edgeSize - 1), VERT_getCo(e->v1, lvl), ss); if (e->numFaces) for (x = 1; x < edgeSize - 1; x++) VertDataMulN(EDGE_getCo(e, lvl, x), 1.0f / e->numFaces, ss); } /* copy */ for (i = 0; i < numEffectedF; i++) { CCGFace *f = effectedF[i]; VertDataMulN((float *)FACE_getCenterData(f), 1.0f / f->numVerts, ss); for (S = 0; S < f->numVerts; S++) for (x = 1; x < gridSize - 1; x++) VertDataMulN(FACE_getIECo(f, lvl, S, x), 0.5f, ss); for (S = 0; S < f->numVerts; S++) { int prevS = (S + f->numVerts - 1) % f->numVerts; CCGEdge *e = FACE_getEdges(f)[S]; CCGEdge *prevE = FACE_getEdges(f)[prevS]; VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), (float *)FACE_getCenterData(f), ss); VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl), ss); for (x = 1; x < gridSize - 1; x++) { VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x), ss); VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x), ss); } for (x = 0; x < gridSize - 1; x++) { int eI = gridSize - 1 - x; VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss); VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize), ss); } VertDataCopy(FACE_getIECo(f, lvl, S, 0), (float *)FACE_getCenterData(f), ss); VertDataCopy(FACE_getIECo(f, lvl, S, gridSize - 1), FACE_getIFCo(f, lvl, S, gridSize - 1, 0), ss); } } for (i = 0; i < numEffectedV; i++) effectedV[i]->flags = 0; for (i = 0; i < numEffectedE; i++) effectedE[i]->flags = 0; for (i = 0; i < numEffectedF; i++) effectedF[i]->flags = 0; MEM_freeN(effectedE); MEM_freeN(effectedV); if (freeF) MEM_freeN(effectedF); return eCCGError_None; }