Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h1
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h1
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c217
-rw-r--r--source/blender/blenkernel/intern/multires.c172
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c12
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c5
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c6
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 {