diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-12-03 21:35:37 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-12-03 21:35:37 +0300 |
commit | 010c99deb271c629742e32f5e7922d357cafc9f3 (patch) | |
tree | f2ad8145f5eb7d3160f3e8e1991df0a1c07c2172 /source/blender/blenkernel/intern | |
parent | e10ae8a1a29459157f2135aad682b01efaaee88f (diff) |
Sculpt Branch:
* Multithread parts of multires and subsurf. Only loops working on
face grid data and do no memory allocation have been multithreaded,
others would be more complicated.
* Force some CCGSubsurf functions to be inlined, gives a small overall
speedup in subsurf code.
* Fix sculpting not working correct with transformed objects.
* Fix a few cases of "spikes" on lower level multires levels. There's
still cases where it happens, usually on boundary cornders. The
problem is that in such cases the limit surfaces can be very different
from the low res surface, so the tangent space is very different too..
* Fix crash deleting multires higher levels with level set to 0.
* Fix crashes that happened sometimes when adding faces in editmode.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/CCGSubSurf.c | 217 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 172 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 12 |
3 files changed, 190 insertions, 211 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index 7c2c6d4d99e..cc2bd531fe6 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -8,6 +8,12 @@ #include "BLO_sys_types.h" // for intptr_t support +#ifdef _MSC_VER +#define CCG_INLINE __inline +#else +#define CCG_INLINE inline +#endif + /* used for normalize_v3 in BLI_math_vector * float.h's FLT_EPSILON causes trouble with subsurf normals - campbell */ #define EPSILON (1.0e-35f) @@ -523,19 +529,19 @@ static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int return f; } -static void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize) { +static CCG_INLINE void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize) { int maxGridSize = 1 + (1<<(levels-1)); int spacing = 1<<(levels-lvl); byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize)); return &gridBase[dataSize*x*spacing]; } -static void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize) { +static CCG_INLINE void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize) { int maxGridSize = 1 + (1<<(levels-1)); int spacing = 1<<(levels-lvl); byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize)); return &gridBase[dataSize*(maxGridSize + (y*maxGridSize + x)*spacing)]; } -static float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) { +static CCG_INLINE float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) { int maxGridSize = 1 + (1<<(levels-1)); int spacing = 1<<(levels-lvl); byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize)); @@ -548,7 +554,7 @@ static int _face_getVertIndex(CCGFace *f, CCGVert *v) { return i; return -1; } -static void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, int levels, int dataSize) { +static CCG_INLINE void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, int levels, int dataSize) { int maxGridSize = 1 + (1<<(levels-1)); int spacing = 1<<(levels-lvl); int S, x, y, cx, cy; @@ -1146,9 +1152,11 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss, int normalDataOffset = ss->normalDataOffset; int vertDataSize = ss->meshIFC.vertDataSize; + #pragma omp parallel for private(ptrIdx) schedule(static) for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { CCGFace *f = (CCGFace*) effectedF[ptrIdx]; int S, x, y; + float no[3]; for (S=0; S<f->numVerts; S++) { for (y=0; y<gridSize-1; y++) @@ -1164,12 +1172,6 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss, if (FACE_getVerts(f)[S]->flags&Vert_eEffected) NormZero(FACE_getIFNo(f, lvl, S, gridSize-1, gridSize-1)); } - } - - for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCGFace *f = (CCGFace*) effectedF[ptrIdx]; - int S, x, y; - float no[3]; for (S=0; S<f->numVerts; S++) { int yLimit = !(FACE_getEdges(f)[(S-1+f->numVerts)%f->numVerts]->flags&Edge_eEffected); @@ -1275,18 +1277,16 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss, } } } + + #pragma omp parallel for private(ptrIdx) schedule(static) for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { CCGFace *f = (CCGFace*) effectedF[ptrIdx]; - int S; + int S, x, y; for (S=0; S<f->numVerts; S++) { NormCopy(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, gridSize-1), FACE_getIFNo(f, lvl, S, gridSize-1, 0)); } - } - for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCGFace *f = (CCGFace*) effectedF[ptrIdx]; - int S, x, y; for (S=0; S<f->numVerts; S++) { for (y=0; y<gridSize; y++) { @@ -1320,12 +1320,14 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, int edgeSize = 1 + (1<<curLvl); int gridSize = 1 + (1<<(curLvl-1)); int nextLvl = curLvl+1; - int ptrIdx, S, y, x, i, cornerIdx; - void *q = ss->q, *r = ss->r; + int ptrIdx, cornerIdx, i; int vertDataSize = ss->meshIFC.vertDataSize; + void *q = ss->q, *r = ss->r; + #pragma omp parallel for private(ptrIdx) schedule(static) for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S, x, y; /* interior face midpoints * o old interior face points @@ -1406,6 +1408,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { CCGEdge *e = (CCGEdge*) effectedE[ptrIdx]; float sharpness = EDGE_getSharpness(e, curLvl); + int x, j; if (_edge_isBoundary(e) || sharpness>1.0) { for (x=0; x<edgeSize-1; x++) { @@ -1429,8 +1432,8 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, VertDataCopy(q, co0); VertDataAdd(q, co1); - for (i=0; i<e->numFaces; i++) { - CCGFace *f = e->faces[i]; + for (j=0; j<e->numFaces; j++) { + CCGFace *f = e->faces[j]; VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx, 1, subdivLevels, vertDataSize)); numFaces++; } @@ -1460,10 +1463,10 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, void *nCo = VERT_getCo(v, nextLvl); int sharpCount = 0, allSharp = 1; float avgSharpness = 0.0; - int seam = VERT_seam(v), seamEdges = 0; + int j, seam = VERT_seam(v), seamEdges = 0; - for (i=0; i<v->numEdges; i++) { - CCGEdge *e = v->edges[i]; + for (j=0; j<v->numEdges; j++) { + CCGEdge *e = v->edges[j]; float sharpness = EDGE_getSharpness(e, curLvl); if (seam && _edge_isBoundary(e)) @@ -1493,8 +1496,8 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, int numBoundary = 0; VertDataZero(r); - for (i=0; i<v->numEdges; i++) { - CCGEdge *e = v->edges[i]; + for (j=0; j<v->numEdges; j++) { + CCGEdge *e = v->edges[j]; if (_edge_isBoundary(e)) { VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize)); numBoundary++; @@ -1510,15 +1513,15 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, int numEdges = 0, numFaces = 0; VertDataZero(q); - for (i=0; i<v->numFaces; i++) { - CCGFace *f = v->faces[i]; + for (j=0; j<v->numFaces; j++) { + CCGFace *f = v->faces[j]; VertDataAdd(q, FACE_getIFCo(f, nextLvl, _face_getVertIndex(f,v), cornerIdx, cornerIdx)); numFaces++; } VertDataMulN(q, 1.0f/numFaces); VertDataZero(r); - for (i=0; i<v->numEdges; i++) { - CCGEdge *e = v->edges[i]; + for (j=0; j<v->numEdges; j++) { + CCGEdge *e = v->edges[j]; VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1,vertDataSize)); numEdges++; } @@ -1540,8 +1543,8 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, allSharp = 1; } - for (i=0; i<v->numEdges; i++) { - CCGEdge *e = v->edges[i]; + for (j=0; j<v->numEdges; j++) { + CCGEdge *e = v->edges[j]; float sharpness = EDGE_getSharpness(e, curLvl); if (seam) { @@ -1585,6 +1588,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, float sharpness = EDGE_getSharpness(e, curLvl); int sharpCount = 0; float avgSharpness = 0.0; + int x, j; if (sharpness!=0.0f) { sharpCount = 2; @@ -1622,8 +1626,8 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, VertDataZero(r); VertDataAdd(r, EDGE_getCo(e, curLvl, x-1)); VertDataAdd(r, EDGE_getCo(e, curLvl, x+1)); - for (i=0; i<e->numFaces; i++) { - CCGFace *f = e->faces[i]; + for (j=0; j<e->numFaces; j++) { + CCGFace *f = e->faces[j]; VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx-1, 1, subdivLevels, vertDataSize)); VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx+1, 1, subdivLevels, vertDataSize)); @@ -1654,52 +1658,91 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, } } - for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + #pragma omp parallel private(ptrIdx) + { + void *q, *r; - /* interior center point shift - * o old face center point (shifting) - * o old interior edge points - * o new interior face midpoints - */ - VertDataZero(q); - for (S=0; S<f->numVerts; S++) { - VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1)); - } - VertDataMulN(q, 1.0f/f->numVerts); - VertDataZero(r); - for (S=0; S<f->numVerts; S++) { - VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1)); + #pragma omp critical + { + q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize); + r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize); } - VertDataMulN(r, 1.0f/f->numVerts); - VertDataMulN(FACE_getCenterData(f), f->numVerts-2.0f); - VertDataAdd(FACE_getCenterData(f), q); - VertDataAdd(FACE_getCenterData(f), r); - VertDataMulN(FACE_getCenterData(f), 1.0f/f->numVerts); + #pragma omp for schedule(static) + for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { + CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S, x, y; - for (S=0; S<f->numVerts; S++) { - /* interior face shift - * o old interior face point (shifting) - * o new interior edge midpoints + /* interior center point shift + * o old face center point (shifting) + * o old interior edge points * o new interior face midpoints */ - for (x=1; x<gridSize-1; x++) { - for (y=1; y<gridSize-1; y++) { + VertDataZero(q); + for (S=0; S<f->numVerts; S++) { + VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1)); + } + VertDataMulN(q, 1.0f/f->numVerts); + VertDataZero(r); + for (S=0; S<f->numVerts; S++) { + VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1)); + } + VertDataMulN(r, 1.0f/f->numVerts); + + VertDataMulN(FACE_getCenterData(f), f->numVerts-2.0f); + VertDataAdd(FACE_getCenterData(f), q); + VertDataAdd(FACE_getCenterData(f), r); + VertDataMulN(FACE_getCenterData(f), 1.0f/f->numVerts); + + for (S=0; S<f->numVerts; S++) { + /* interior face shift + * o old interior face point (shifting) + * o new interior edge midpoints + * o new interior face midpoints + */ + for (x=1; x<gridSize-1; x++) { + for (y=1; y<gridSize-1; y++) { + int fx = x*2; + int fy = y*2; + void *co = FACE_getIFCo(f, curLvl, S, x, y); + void *nCo = FACE_getIFCo(f, nextLvl, S, fx, fy); + + VertDataAvg4(q, FACE_getIFCo(f, nextLvl, S, fx-1, fy-1), + FACE_getIFCo(f, nextLvl, S, fx+1, fy-1), + FACE_getIFCo(f, nextLvl, S, fx+1, fy+1), + FACE_getIFCo(f, nextLvl, S, fx-1, fy+1)); + + VertDataAvg4(r, FACE_getIFCo(f, nextLvl, S, fx-1, fy+0), + FACE_getIFCo(f, nextLvl, S, fx+1, fy+0), + FACE_getIFCo(f, nextLvl, S, fx+0, fy-1), + FACE_getIFCo(f, nextLvl, S, fx+0, fy+1)); + + VertDataCopy(nCo, co); + VertDataSub(nCo, q); + VertDataMulN(nCo, 0.25f); + VertDataAdd(nCo, r); + } + } + + /* interior edge interior shift + * o old interior edge point (shifting) + * o new interior edge midpoints + * o new interior face midpoints + */ + for (x=1; x<gridSize-1; x++) { int fx = x*2; - int fy = y*2; - void *co = FACE_getIFCo(f, curLvl, S, x, y); - void *nCo = FACE_getIFCo(f, nextLvl, S, fx, fy); + void *co = FACE_getIECo(f, curLvl, S, x); + void *nCo = FACE_getIECo(f, nextLvl, S, fx); - VertDataAvg4(q, FACE_getIFCo(f, nextLvl, S, fx-1, fy-1), - FACE_getIFCo(f, nextLvl, S, fx+1, fy-1), - FACE_getIFCo(f, nextLvl, S, fx+1, fy+1), - FACE_getIFCo(f, nextLvl, S, fx-1, fy+1)); + VertDataAvg4(q, FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx-1), + FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx+1), + FACE_getIFCo(f, nextLvl, S, fx+1, +1), + FACE_getIFCo(f, nextLvl, S, fx-1, +1)); - VertDataAvg4(r, FACE_getIFCo(f, nextLvl, S, fx-1, fy+0), - FACE_getIFCo(f, nextLvl, S, fx+1, fy+0), - FACE_getIFCo(f, nextLvl, S, fx+0, fy-1), - FACE_getIFCo(f, nextLvl, S, fx+0, fy+1)); + VertDataAvg4(r, FACE_getIECo(f, nextLvl, S, fx-1), + FACE_getIECo(f, nextLvl, S, fx+1), + FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx), + FACE_getIFCo(f, nextLvl, S, fx, 1)); VertDataCopy(nCo, co); VertDataSub(nCo, q); @@ -1707,32 +1750,12 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, VertDataAdd(nCo, r); } } + } - /* interior edge interior shift - * o old interior edge point (shifting) - * o new interior edge midpoints - * o new interior face midpoints - */ - for (x=1; x<gridSize-1; x++) { - int fx = x*2; - void *co = FACE_getIECo(f, curLvl, S, x); - void *nCo = FACE_getIECo(f, nextLvl, S, fx); - - VertDataAvg4(q, FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx-1), - FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx+1), - FACE_getIFCo(f, nextLvl, S, fx+1, +1), - FACE_getIFCo(f, nextLvl, S, fx-1, +1)); - - VertDataAvg4(r, FACE_getIECo(f, nextLvl, S, fx-1), - FACE_getIECo(f, nextLvl, S, fx+1), - FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx), - FACE_getIFCo(f, nextLvl, S, fx, 1)); - - VertDataCopy(nCo, co); - VertDataSub(nCo, q); - VertDataMulN(nCo, 0.25f); - VertDataAdd(nCo, r); - } + #pragma omp critical + { + CCGSUBSURF_free(ss, q); + CCGSUBSURF_free(ss, r); } } @@ -1740,13 +1763,19 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, edgeSize = 1 + (1<<(nextLvl)); gridSize = 1 + (1<<((nextLvl)-1)); cornerIdx = gridSize-1; + + #pragma omp parallel for private(i) schedule(static) for (i=0; i<numEffectedE; i++) { CCGEdge *e = effectedE[i]; VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl)); VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize-1), VERT_getCo(e->v1, nextLvl)); } + + #pragma omp parallel for private(i) schedule(static) for (i=0; i<numEffectedF; i++) { CCGFace *f = effectedF[i]; + int S, x; + for (S=0; S<f->numVerts; S++) { CCGEdge *e = FACE_getEdges(f)[S]; CCGEdge *prevE = FACE_getEdges(f)[(S+f->numVerts-1)%f->numVerts]; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index a709b45f60c..69659db3ba7 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -248,39 +248,45 @@ void multiresModifier_del_levels(struct MultiresModifierData *mmd, struct Object int lvl = multires_get_level(ob, mmd, 0); int levels = mmd->totlvl - lvl; MDisps *mdisps; - + CustomData_external_read(&me->fdata, CD_MASK_MDISPS, me->totface); mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS); multires_force_update(ob); if(mdisps && levels > 0 && direction == 1) { - int nsize = multires_side_tot[lvl]; - int hsize = multires_side_tot[mmd->totlvl]; - int i; + if(lvl > 0) { + int nsize = multires_side_tot[lvl]; + int hsize = multires_side_tot[mmd->totlvl]; + int i; - for(i = 0; i < me->totface; ++i) { - MDisps *mdisp= &mdisps[i]; - float (*disps)[3], (*ndisps)[3], (*hdisps)[3]; - int nvert = (me->mface[i].v4)? 4: 3; - int totdisp = multires_grid_tot[lvl]*nvert; - int S; + for(i = 0; i < me->totface; ++i) { + MDisps *mdisp= &mdisps[i]; + float (*disps)[3], (*ndisps)[3], (*hdisps)[3]; + int nvert = (me->mface[i].v4)? 4: 3; + int totdisp = multires_grid_tot[lvl]*nvert; + int S; - disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps"); + disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps"); - ndisps = disps; - hdisps = mdisp->disps; + ndisps = disps; + hdisps = mdisp->disps; - for(S = 0; S < nvert; S++) { - multires_copy_grid(ndisps, hdisps, nsize, hsize); + for(S = 0; S < nvert; S++) { + multires_copy_grid(ndisps, hdisps, nsize, hsize); - ndisps += nsize*nsize; - hdisps += hsize*hsize; - } + ndisps += nsize*nsize; + hdisps += hsize*hsize; + } - MEM_freeN(mdisp->disps); - mdisp->disps = disps; - mdisp->totdisp = totdisp; + MEM_freeN(mdisp->disps); + mdisp->disps = disps; + mdisp->totdisp = totdisp; + } + } + else { + CustomData_external_remove(&me->fdata, CD_MDISPS, me->totface); + CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface); } } @@ -409,105 +415,27 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updat multires_set_tot_level(ob, mmd, totlvl); } -static void grid_adjacent_rotate(int rotation, int gridSize, int *x, int *y) -{ - /* we rotate (rotation * 90°) counterclockwise around center */ - int nx, ny; - - switch(rotation) { - case 0: nx = *x; ny = *y; break; - case 1: nx = *y; ny = *x; break; - case 2: nx = *x; ny = *y; break; //gridSize - 1 - *x; ny = gridSize - 1 - *y; break; - case 3: nx = *y; ny = *x; break; - } - - *x = nx; - *y = ny; -} - -static void grid_adjacent_jump(DMGridAdjacency *adj, int gridSize, int *index, int *x, int *y) -{ - if(*x < 0) { - if(adj->index[3] == -1) { - /* no adjacent grid, clamp */ - *x = 0; - } - else { - /* jump to adjacent grid */ - *index = adj->index[3]; - *x += gridSize; - grid_adjacent_rotate(adj->rotation[3], gridSize, x, y); - } - } - else if(*x >= gridSize) { - if(adj->index[1] == -1) { - /* no adjacent grid, take a step back */ - *x = gridSize - 1; - } - else { - /* jump to adjacent grid */ - *index = adj->index[1]; - *x -= gridSize; - grid_adjacent_rotate(adj->rotation[1], gridSize, x, y); - } - } - else if(*y < 0) { - if(adj->index[0] == -1) { - /* no adjacent grid, clamp */ - *y = 0; - } - else { - /* jump to adjacent grid */ - *index = adj->index[0]; - *y += gridSize; - grid_adjacent_rotate(adj->rotation[0], gridSize, x, y); - } - } - else if(*y >= gridSize) { - if(adj->index[2] == -1) { - /* no adjacent grid, take a step back */ - *y = gridSize - 1; - } - else { - /* jump to adjacent grid */ - *index = adj->index[2]; - *y -= gridSize; - grid_adjacent_rotate(adj->rotation[2], gridSize, x, y); - } - } -} - -static void grid_tangent(DMGridAdjacency *adj, int gridSize, int index, int x, int y, int axis, DMGridData **gridData, float t[3]) +static void grid_tangent(int gridSize, int index, int x, int y, int axis, DMGridData **gridData, float t[3]) { - int jindex = index, jx = x, jy = y; - if(axis == 0) { - if(adj->index[1] == -1 && x == gridSize - 1) { - if(adj->index[2] == -1 && y == gridSize - 1) + if(x == gridSize - 1) { + if(y == gridSize - 1) sub_v3_v3v3(t, gridData[index][x + gridSize*(y - 1)].co, gridData[index][x - 1 + gridSize*(y - 1)].co); else sub_v3_v3v3(t, gridData[index][x + gridSize*y].co, gridData[index][x - 1 + gridSize*y].co); } - else { - jx += 1; - grid_adjacent_jump(adj, gridSize, &jindex, &jx, &jy); - sub_v3_v3v3(t, gridData[jindex][jx + gridSize*jy].co, gridData[index][x + gridSize*y].co); - } + else + sub_v3_v3v3(t, gridData[index][x + 1 + gridSize*y].co, gridData[index][x + gridSize*y].co); } else if(axis == 1) { - if(adj->index[2] == -1 && y == gridSize - 1) { - if(adj->index[1] == -1 && x == gridSize - 1) { + if(y == gridSize - 1) { + if(x == gridSize - 1) sub_v3_v3v3(t, gridData[index][x - 1 + gridSize*y].co, gridData[index][x - 1 + gridSize*(y - 1)].co); - } - else { + else sub_v3_v3v3(t, gridData[index][x + gridSize*y].co, gridData[index][x + gridSize*(y - 1)].co); - } - } - else { - jy += 1; - grid_adjacent_jump(adj, gridSize, &jindex, &jx, &jy); - sub_v3_v3v3(t, gridData[jindex][jx + gridSize*jy].co, gridData[index][x + gridSize*y].co); } + else + sub_v3_v3v3(t, gridData[index][x + gridSize*(y + 1)].co, gridData[index][x + gridSize*y].co); } } @@ -515,28 +443,36 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm; DMGridData **gridData, **subGridData; - DMGridAdjacency *gridAdjacency; MFace *mface = me->mface; MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS); - int i, S, x, y, numGrids, gIndex, gridSize, dGridSize, dSkip; + int *gridOffset; + int i, numGrids, gridSize, dGridSize, dSkip; numGrids = dm->getNumGrids(dm); gridSize = dm->getGridSize(dm); gridData = dm->getGridData(dm); - gridAdjacency = dm->getGridAdjacency(dm); + gridOffset = dm->getGridOffset(dm); subGridData = (oldGridData)? oldGridData: gridData; dGridSize = multires_side_tot[totlvl]; dSkip = (dGridSize-1)/(gridSize-1); - for(gIndex = 0, i = 0; i < me->totface; ++i) { + #pragma omp parallel for private(i) schedule(static) + for(i = 0; i < me->totface; ++i) { const int numVerts = mface[i].v4 ? 4 : 3; MDisps *mdisp = &mdisps[i]; + int S, x, y, gIndex = gridOffset[i]; + + /* when adding new faces in edit mode, need to allocate disps */ + if(!mdisp->disps) + #pragma omp critical + { + multires_reallocate_mdisps(me, mdisps, totlvl); + } for(S = 0; S < numVerts; ++S, ++gIndex) { DMGridData *grid = gridData[gIndex]; DMGridData *subgrid = subGridData[gIndex]; - DMGridAdjacency *adj = &gridAdjacency[gIndex]; float (*dispgrid)[3] = &mdisp->disps[S*dGridSize*dGridSize]; for(y = 0; y < gridSize; y++) { @@ -548,12 +484,16 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int float mat[3][3], tx[3], ty[3], disp[3], d[3]; /* construct tangent space matrix */ - grid_tangent(adj, gridSize, gIndex, x, y, 0, subGridData, tx); + grid_tangent(gridSize, gIndex, x, y, 0, subGridData, tx); normalize_v3(tx); - grid_tangent(adj, gridSize, gIndex, x, y, 1, subGridData, ty); + grid_tangent(gridSize, gIndex, x, y, 1, subGridData, ty); normalize_v3(ty); + //mul_v3_fl(tx, 1.0f/(gridSize-1)); + //mul_v3_fl(ty, 1.0f/(gridSize-1)); + //cross_v3_v3v3(no, tx, ty); + column_vectors_to_mat3(mat, tx, ty, no); if(!invert) { diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 716229e6ead..c9d84670044 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1894,6 +1894,7 @@ static void ccgDM_release(DerivedMesh *dm) { if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces); if(ccgdm->gridData) MEM_freeN(ccgdm->gridData); if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency); + if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset); if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss); MEM_freeN(ccgdm->edgeFlags); MEM_freeN(ccgdm->faceFlags); @@ -2112,7 +2113,7 @@ static void ccgdm_create_grids(DerivedMesh *dm) ccgdm->gridData = gridData; ccgdm->gridFaces = gridFaces; ccgdm->gridAdjacency = gridAdjacency; - MEM_freeN(gridOffset); + ccgdm->gridOffset = gridOffset; } static DMGridData **ccgDM_getGridData(DerivedMesh *dm) @@ -2131,6 +2132,14 @@ static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm) return ccgdm->gridAdjacency; } +static int *ccgDM_getGridOffset(DerivedMesh *dm) +{ + CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; + + ccgdm_create_grids(dm); + return ccgdm->gridOffset; +} + static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) { CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; @@ -2209,6 +2218,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgdm->dm.getGridSize = ccgDM_getGridSize; ccgdm->dm.getGridData = ccgDM_getGridData; ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency; + ccgdm->dm.getGridOffset = ccgDM_getGridOffset; ccgdm->dm.getPBVH = ccgDM_getPBVH; ccgdm->dm.getVertCos = ccgdm_getVertCos; |