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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-03 21:35:37 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-03 21:35:37 +0300
commit010c99deb271c629742e32f5e7922d357cafc9f3 (patch)
treef2ad8145f5eb7d3160f3e8e1991df0a1c07c2172 /source
parente10ae8a1a29459157f2135aad682b01efaaee88f (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')
-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 {