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
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2010-01-30 12:32:05 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2010-01-30 12:32:05 +0300
commita7f2c3fca85823fbe2f0f708846fd9ad9ddfb2c9 (patch)
tree80f2263653e7ac410515422ec04c8e31f5ecb72e /source/blender/blenkernel/intern/CCGSubSurf.c
parent3e71c3cbac458955de62f782b67bb128f481f1df (diff)
Fix #20505: subsurf normals where not being set correct on correct from
subsurf derivedmesh to regular (derived)mesh, causing drawing errors on apply and following modifiers to work incorrect.
Diffstat (limited to 'source/blender/blenkernel/intern/CCGSubSurf.c')
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index dc863869ad8..60e1015f190 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -467,12 +467,10 @@ static void *_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize) {
int levelBase = lvl + (1<<lvl) - 1;
return &EDGE_getLevelData(e)[dataSize*(levelBase + x)];
}
-#if 0
static float *_edge_getNo(CCGEdge *e, int lvl, int x, int dataSize, int normalDataOffset) {
int levelBase = lvl + (1<<lvl) - 1;
return (float*) &EDGE_getLevelData(e)[dataSize*(levelBase + x) + normalDataOffset];
}
-#endif
static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSize) {
int levelBase = lvl + (1<<lvl) - 1;
if (v==e->v0) {
@@ -535,6 +533,12 @@ static CCG_INLINE void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int lev
byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize));
return &gridBase[dataSize*x*spacing];
}
+static CCG_INLINE void *_face_getIENo(CCGFace *f, int lvl, int S, int x, 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));
+ return &gridBase[dataSize*x*spacing + normalDataOffset];
+}
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);
@@ -1139,8 +1143,11 @@ CCGError ccgSubSurf_processSync(CCGSubSurf *ss) {
return eCCGError_None;
}
+#define VERT_getNo(e, lvl) _vert_getNo(e, lvl, vertDataSize, normalDataOffset)
+#define EDGE_getNo(e, lvl, x) _edge_getNo(e, lvl, x, vertDataSize, normalDataOffset)
#define FACE_getIFNo(f, lvl, S, x, y) _face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset)
#define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize)
+#define FACE_getIENo(f, lvl, S, x) _face_getIENo(f, lvl, S, x, subdivLevels, vertDataSize, normalDataOffset)
static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
CCGVert **effectedV, CCGEdge **effectedE, CCGFace **effectedF,
int numEffectedV, int numEffectedE, int numEffectedF) {
@@ -1304,6 +1311,26 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
}
}
}
+
+ VertDataCopy((float*)((byte*)FACE_getCenterData(f) + normalDataOffset),
+ FACE_getIFNo(f, lvl, S, 0, 0));
+
+ for (x=1; x<gridSize-1; x++)
+ NormCopy(FACE_getIENo(f, lvl, S, x),
+ FACE_getIFNo(f, lvl, S, x, 0));
+ }
+ }
+
+ for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
+ CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
+
+ if (e->numFaces) {
+ CCGFace *f = e->faces[0];
+ int x;
+
+ for (x=0; x<edgeSize; x++)
+ NormCopy(EDGE_getNo(e, lvl, x),
+ _face_getIFNoEdge(f, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
}
}
}