diff options
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_subsurf.h | 1 | ||||
-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 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 5 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 6 |
7 files changed, 198 insertions, 216 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index bcafc4c48b2..1f6a8f955ba 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -151,6 +151,7 @@ struct DerivedMesh { int (*getGridSize)(DerivedMesh *dm); DMGridData **(*getGridData)(DerivedMesh *dm); DMGridAdjacency *(*getGridAdjacency)(DerivedMesh *dm); + int *(*getGridOffset)(DerivedMesh *dm); /* Iterate over each mapped vertex in the derived mesh, calling the * given function with the original vert and the mapped vert's new diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index 7b8adb7cb8e..0a18850e3b7 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -73,6 +73,7 @@ typedef struct CCGDerivedMesh { struct DMGridData **gridData; struct DMGridAdjacency *gridAdjacency; + int *gridOffset; struct _CCGFace **gridFaces; struct { 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; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 7644751d61e..b39a2912c02 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1726,12 +1726,17 @@ int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float ou SculptSession *ss= vc->obact->sculpt; StrokeCache *cache= ss->cache; float ray_start[3], ray_normal[3]; + float obimat[4][4]; float mval[2] = {mouse[0] - vc->ar->winrct.xmin, mouse[1] - vc->ar->winrct.ymin}; SculptRaycastData srd; viewray(vc->ar, vc->v3d, mval, ray_start, ray_normal); + invert_m4_m4(obimat, ss->ob->obmat); + mul_m4_v3(obimat, ray_start); + mul_mat3_m4_v3(obimat, ray_normal); + srd.ss = vc->obact->sculpt; srd.ray_start = ray_start; srd.ray_normal = ray_normal; diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 9db7f9b1ce9..4c55f759e47 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -379,14 +379,10 @@ void GPU_drawobject_free( DerivedMesh *dm ) dm->drawObject = 0; } -/* Convenience struct for building the VBO. - TODO: check that (lack-of) padding is OK, - also check performance of short vs float for normals */ +/* Convenience struct for building the VBO. */ typedef struct { float co[3]; short no[3]; - - char pad[14]; } VertexBufferFormat; typedef struct { |