Revision: 24882
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24882
Author:   blendix
Date:     2009-11-25 13:27:21 +0100 (Wed, 25 Nov 2009)

Log Message:
-----------
Sculpt: CCGSubsurf new functions to update normals, update subdivision
levels, copy coordinates from face grids, and stitch together face grids.

Modified Paths:
--------------
    branches/sculpt25/source/blender/blenkernel/intern/CCGSubSurf.c
    branches/sculpt25/source/blender/blenkernel/intern/CCGSubSurf.h

Modified: branches/sculpt25/source/blender/blenkernel/intern/CCGSubSurf.c
===================================================================
--- branches/sculpt25/source/blender/blenkernel/intern/CCGSubSurf.c     
2009-11-25 12:04:11 UTC (rev 24881)
+++ branches/sculpt25/source/blender/blenkernel/intern/CCGSubSurf.c     
2009-11-25 12:27:21 UTC (rev 24882)
@@ -1130,6 +1130,643 @@
        return eCCGError_None;
 }
 
+#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)
+static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
+       CCGVert **effectedV, CCGEdge **effectedE, CCGFace **effectedF,
+       int numEffectedV, int numEffectedE, int numEffectedF) {
+       int i,ptrIdx;
+       int subdivLevels = ss->subdivLevels;
+       int lvl = ss->subdivLevels;
+       int edgeSize = 1 + (1<<lvl);
+       int gridSize = 1 + (1<<(lvl-1));
+       int normalDataOffset = ss->normalDataOffset;
+       int vertDataSize = ss->meshIFC.vertDataSize;
+
+       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-1; y++)
+                               for (x=0; x<gridSize-1; x++)
+                                       NormZero(FACE_getIFNo(f, lvl, S, x, y));
+
+                       if 
(FACE_getEdges(f)[(S-1+f->numVerts)%f->numVerts]->flags&Edge_eEffected)
+                               for (x=0; x<gridSize-1; x++)
+                                       NormZero(FACE_getIFNo(f, lvl, S, x, 
gridSize-1));
+                       if (FACE_getEdges(f)[S]->flags&Edge_eEffected)
+                               for (y=0; y<gridSize-1; y++)
+                                       NormZero(FACE_getIFNo(f, lvl, S, 
gridSize-1, y));
+                       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);
+                       int xLimit = 
!(FACE_getEdges(f)[S]->flags&Edge_eEffected);
+                       int yLimitNext = xLimit;
+                       int xLimitPrev = yLimit;
+                       
+                       for (y=0; y<gridSize - 1; y++) {
+                               for (x=0; x<gridSize - 1; x++) {
+                                       int xPlusOk = (!xLimit || x<gridSize-2);
+                                       int yPlusOk = (!yLimit || y<gridSize-2);
+
+                                       FACE_calcIFNo(f, lvl, S, x, y, no);
+
+                                       NormAdd(FACE_getIFNo(f, lvl, S, x+0, 
y+0), no);
+                                       if (xPlusOk)
+                                               NormAdd(FACE_getIFNo(f, lvl, S, 
x+1, y+0), no);
+                                       if (yPlusOk)
+                                               NormAdd(FACE_getIFNo(f, lvl, S, 
x+0, y+1), no);
+                                       if (xPlusOk && yPlusOk) {
+                                               if (x<gridSize-2 || 
y<gridSize-2 || FACE_getVerts(f)[S]->flags&Vert_eEffected) {
+                                                       NormAdd(FACE_getIFNo(f, 
lvl, S, x+1, y+1), no);
+                                               }
+                                       }
+
+                                       if (x==0 && y==0) {
+                                               int K;
+
+                                               if (!yLimitNext || 1<gridSize-1)
+                                                       NormAdd(FACE_getIFNo(f, 
lvl, (S+1)%f->numVerts, 0, 1), no);
+                                               if (!xLimitPrev || 1<gridSize-1)
+                                                       NormAdd(FACE_getIFNo(f, 
lvl, (S-1+f->numVerts)%f->numVerts, 1, 0), no);
+
+                                               for (K=0; K<f->numVerts; K++) {
+                                                       if (K!=S) {
+                                                               
NormAdd(FACE_getIFNo(f, lvl, K, 0, 0), no);
+                                                       }
+                                               }
+                                       } else if (y==0) {
+                                               NormAdd(FACE_getIFNo(f, lvl, 
(S+1)%f->numVerts, 0, x), no);
+                                               if (!yLimitNext || x<gridSize-2)
+                                                       NormAdd(FACE_getIFNo(f, 
lvl, (S+1)%f->numVerts, 0, x+1), no);
+                                       } else if (x==0) {
+                                               NormAdd(FACE_getIFNo(f, lvl, 
(S-1+f->numVerts)%f->numVerts, y, 0), no);
+                                               if (!xLimitPrev || y<gridSize-2)
+                                                       NormAdd(FACE_getIFNo(f, 
lvl, (S-1+f->numVerts)%f->numVerts, y+1, 0), no);
+                                       }
+                               }
+                       }
+               }
+       }
+               // XXX can I reduce the number of normalisations here?
+       for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) {
+               CCGVert *v = (CCGVert*) effectedV[ptrIdx];
+               float length, *no = _vert_getNo(v, lvl, vertDataSize, 
normalDataOffset);
+
+               NormZero(no);
+
+               for (i=0; i<v->numFaces; i++) {
+                       CCGFace *f = v->faces[i];
+                       NormAdd(no, FACE_getIFNo(f, lvl, 
_face_getVertIndex(f,v), gridSize-1, gridSize-1));
+               }
+
+               length = sqrt(no[0]*no[0] + no[1]*no[1] + no[2]*no[2]);
+
+               if (length>FLT_EPSILON) {
+                       float invLength = 1.0f/length;
+                       no[0] *= invLength;
+                       no[1] *= invLength;
+                       no[2] *= invLength;
+               } else {
+                       NormZero(no);
+               }
+
+               for (i=0; i<v->numFaces; i++) {
+                       CCGFace *f = v->faces[i];
+                       NormCopy(FACE_getIFNo(f, lvl, _face_getVertIndex(f,v), 
gridSize-1, gridSize-1), no);
+               }
+       }
+       for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
+               CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
+
+               if (e->numFaces) {
+                       CCGFace *fLast = e->faces[e->numFaces-1];
+                       int x;
+
+                       for (i=0; i<e->numFaces-1; i++) {
+                               CCGFace *f = e->faces[i];
+
+                               for (x=1; x<edgeSize-1; x++) {
+                                       NormAdd(_face_getIFNoEdge(fLast, e, 
lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset),
+                                                       _face_getIFNoEdge(f, e, 
lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
+                               }
+                       }
+
+                       for (i=0; i<e->numFaces-1; i++) {
+                               CCGFace *f = e->faces[i];
+
+                               for (x=1; x<edgeSize-1; x++) {
+                                       NormCopy(_face_getIFNoEdge(f, e, lvl, 
x, 0, subdivLevels, vertDataSize, normalDataOffset),
+                                                       
_face_getIFNoEdge(fLast, e, lvl, x, 0, subdivLevels, vertDataSize, 
normalDataOffset));
+                               }
+                       }
+               }
+       }
+       for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
+               CCGFace *f = (CCGFace*) effectedF[ptrIdx];
+               int S;
+
+               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++) {
+                               for (x=0; x<gridSize; x++) {
+                                       float *no = FACE_getIFNo(f, lvl, S, x, 
y);
+                                       float length = sqrt(no[0]*no[0] + 
no[1]*no[1] + no[2]*no[2]);
+
+                                       if (length>FLT_EPSILON) {
+                                               float invLength = 1.0f/length;
+                                               no[0] *= invLength;
+                                               no[1] *= invLength;
+                                               no[2] *= invLength;
+                                       } else {
+                                               NormZero(no);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+#undef FACE_getIFNo
+
+#define VERT_getCo(v, lvl)                             _vert_getCo(v, lvl, 
vertDataSize)
+#define EDGE_getCo(e, lvl, x)                  _edge_getCo(e, lvl, x, 
vertDataSize)
+#define FACE_getIECo(f, lvl, S, x)             _face_getIECo(f, lvl, S, x, 
subdivLevels, vertDataSize)
+#define FACE_getIFCo(f, lvl, S, x, y)  _face_getIFCo(f, lvl, S, x, y, 
subdivLevels, vertDataSize)
+static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
+       CCGVert **effectedV, CCGEdge **effectedE, CCGFace **effectedF,
+       int numEffectedV, int numEffectedE, int numEffectedF, int curLvl) {
+       int subdivLevels = ss->subdivLevels;
+       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 vertDataSize = ss->meshIFC.vertDataSize;
+
+       for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
+               CCGFace *f = (CCGFace*) effectedF[ptrIdx];
+
+                       /* interior face midpoints
+                        *  o old interior face points
+                        */
+               for (S=0; S<f->numVerts; S++) {
+                       for (y=0; y<gridSize-1; y++) {
+                               for (x=0; x<gridSize-1; x++) {
+                                       int fx = 1 + 2*x;
+                                       int fy = 1 + 2*y;
+                                       void *co0 = FACE_getIFCo(f, curLvl, S, 
x+0, y+0);
+                                       void *co1 = FACE_getIFCo(f, curLvl, S, 
x+1, y+0);
+                                       void *co2 = FACE_getIFCo(f, curLvl, S, 
x+1, y+1);
+                                       void *co3 = FACE_getIFCo(f, curLvl, S, 
x+0, y+1);
+                                       void *co = FACE_getIFCo(f, nextLvl, S, 
fx, fy);
+
+                                       VertDataAvg4(co, co0, co1, co2, co3);
+                               }
+                       }
+               }
+
+                       /* interior edge midpoints
+                        *  o old interior edge points
+                        *  o new interior face midpoints
+                        */
+               for (S=0; S<f->numVerts; S++) {
+                       for (x=0; x<gridSize-1; x++) {
+                               int fx = x*2 + 1;
+                               void *co0 = FACE_getIECo(f, curLvl, S, x+0);
+                               void *co1 = FACE_getIECo(f, curLvl, S, x+1);
+                               void *co2 = FACE_getIFCo(f, nextLvl, 
(S+1)%f->numVerts, 1, fx);
+                               void *co3 = FACE_getIFCo(f, nextLvl, S, fx, 1);
+                               void *co = FACE_getIECo(f, nextLvl, S, fx);
+                               
+                               VertDataAvg4(co, co0, co1, co2, co3);
+                       }
+
+                                       /* interior face interior edge midpoints
+                                        *  o old interior face points
+                                        *  o new interior face midpoints
+                                        */
+
+                               /* vertical */
+                       for (x=1; x<gridSize-1; x++) {
+                               for (y=0; y<gridSize-1; y++) {
+                                       int fx = x*2;
+                                       int fy = y*2+1;
+                                       void *co0 = FACE_getIFCo(f, curLvl, S, 
x, y+0);
+                                       void *co1 = FACE_getIFCo(f, curLvl, S, 
x, y+1);
+                                       void *co2 = FACE_getIFCo(f, nextLvl, S, 
fx-1, fy);
+                                       void *co3 = FACE_getIFCo(f, nextLvl, S, 
fx+1, fy);
+                                       void *co = FACE_getIFCo(f, nextLvl, S, 
fx, fy);
+
+                                       VertDataAvg4(co, co0, co1, co2, co3);
+                               }
+                       }
+
+                               /* horizontal */
+                       for (y=1; y<gridSize-1; y++) {
+                               for (x=0; x<gridSize-1; x++) {
+                                       int fx = x*2+1;
+                                       int fy = y*2;
+                                       void *co0 = FACE_getIFCo(f, curLvl, S, 
x+0, y);
+                                       void *co1 = FACE_getIFCo(f, curLvl, S, 
x+1, y);
+                                       void *co2 = FACE_getIFCo(f, nextLvl, S, 
fx, fy-1);
+                                       void *co3 = FACE_getIFCo(f, nextLvl, S, 
fx, fy+1);
+                                       void *co = FACE_getIFCo(f, nextLvl, S, 
fx, fy);
+
+                                       VertDataAvg4(co, co0, co1, co2, co3);
+                               }
+                       }
+               }
+       }
+
+               /* exterior edge midpoints
+                *  o old exterior edge points
+                *  o new interior face midpoints
+                */
+       for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
+               CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
+               float sharpness = EDGE_getSharpness(e, curLvl);
+
+               if (_edge_isBoundary(e) || sharpness>1.0) {
+                       for (x=0; x<edgeSize-1; x++) {
+                               int fx = x*2 + 1;
+                               void *co0 = EDGE_getCo(e, curLvl, x+0);
+                               void *co1 = EDGE_getCo(e, curLvl, x+1);
+                               void *co = EDGE_getCo(e, nextLvl, fx);
+
+                               VertDataCopy(co, co0);
+                               VertDataAdd(co, co1);
+                               VertDataMulN(co, 0.5);
+                       }
+               } else {
+                       for (x=0; x<edgeSize-1; x++) {
+                               int fx = x*2 + 1;
+                               void *co0 = EDGE_getCo(e, curLvl, x+0);
+                               void *co1 = EDGE_getCo(e, curLvl, x+1);
+                               void *co = EDGE_getCo(e, nextLvl, fx);
+                               int numFaces = 0;
+
+                               VertDataCopy(q, co0);
+                               VertDataAdd(q, co1);
+
+                               for (i=0; i<e->numFaces; i++) {
+                                       CCGFace *f = e->faces[i];
+                                       VertDataAdd(q, _face_getIFCoEdge(f, e, 
nextLvl, fx, 1, subdivLevels, vertDataSize));
+                                       numFaces++;
+                               }
+
+                               VertDataMulN(q, 1.0f/(2.0f+numFaces));
+
+                               VertDataCopy(r, co0);
+                               VertDataAdd(r, co1);
+                               VertDataMulN(r, 0.5);
+
+                               VertDataCopy(co, q);
+                               VertDataSub(r, q);
+                               VertDataMulN(r, sharpness);
+                               VertDataAdd(co, r);
+                       }
+               }
+       }
+
+               /* exterior vertex shift
+                *  o old vertex points (shifting)
+                *  o old exterior edge points

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to