forked from bartvdbraak/blender
- Hacked in blender style creasing support to new subsurfs.
I would like to have proper creasing (following what appears to be the informal standard in the subdivision surface literature) but I do not know when I will get to this or how complicated it will be. With this patch CCGSubSurfs should now have the same capabilities as regular subsurfs (barring possible bugs) and so replacing the old implementation is a reasonable possibility.
This commit is contained in:
parent
a4b5ddb371
commit
845ee1e4a1
@ -4,9 +4,12 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "CCGSubSurf.h"
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#define USE_CREASING
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
@ -462,6 +465,15 @@ static void _edge_unlinkMarkAndFree(CCGEdge *e, CCGSubSurf *ss) {
|
|||||||
_edge_free(e, ss);
|
_edge_free(e, ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_CREASING
|
||||||
|
float EDGE_getSharpness(CCGEdge *e, int lvl, CCGSubSurf *ss) {
|
||||||
|
float f,sharpness = f=(((float*) ccgSubSurf_getEdgeUserData(ss, e))[1]);
|
||||||
|
while ((sharpness>1.0) && lvl--)
|
||||||
|
sharpness -= 1.0;
|
||||||
|
return sharpness;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
|
||||||
static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, int levels, int dataSize, CCGSubSurf *ss) {
|
static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, int levels, int dataSize, CCGSubSurf *ss) {
|
||||||
@ -1098,17 +1110,45 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
|
|||||||
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
|
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
|
||||||
CCGFace *f = effectedF[ptrIdx];
|
CCGFace *f = effectedF[ptrIdx];
|
||||||
void *co = FACE_getCenterData(f);
|
void *co = FACE_getCenterData(f);
|
||||||
f->flags = 0;
|
|
||||||
ss->meshIFC.vertDataZero(ss->meshData, co);
|
ss->meshIFC.vertDataZero(ss->meshData, co);
|
||||||
for (i=0; i<f->numVerts; i++) {
|
for (i=0; i<f->numVerts; i++) {
|
||||||
ss->meshIFC.vertDataAdd(ss->meshData, co, VERT_getCo(FACE_getVerts(f)[i], curLvl));
|
ss->meshIFC.vertDataAdd(ss->meshData, co, VERT_getCo(FACE_getVerts(f)[i], curLvl));
|
||||||
}
|
}
|
||||||
ss->meshIFC.vertDataMulN(ss->meshData, co, 1.0f/f->numVerts);
|
ss->meshIFC.vertDataMulN(ss->meshData, co, 1.0f/f->numVerts);
|
||||||
|
|
||||||
|
f->flags = 0;
|
||||||
}
|
}
|
||||||
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
|
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
|
||||||
CCGEdge *e = effectedE[ptrIdx];
|
CCGEdge *e = effectedE[ptrIdx];
|
||||||
void *co = EDGE_getCo(e, nextLvl, 1);
|
void *co = EDGE_getCo(e, nextLvl, 1);
|
||||||
e->flags = 0;
|
#ifdef USE_CREASING
|
||||||
|
float sharpness = EDGE_getSharpness(e, curLvl, ss);
|
||||||
|
|
||||||
|
if (_edge_isBoundary(e) || sharpness>=1.0) {
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, co, VERT_getCo(e->v0, curLvl));
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, co, VERT_getCo(e->v1, curLvl));
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, co, 0.5f);
|
||||||
|
} else {
|
||||||
|
int numFaces = 0;
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, q, VERT_getCo(e->v0, curLvl));
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, VERT_getCo(e->v1, curLvl));
|
||||||
|
for (i=0; i<e->numFaces; i++) {
|
||||||
|
CCGFace *f = e->faces[i];
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, FACE_getCenterData(f));
|
||||||
|
numFaces++;
|
||||||
|
}
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 1.0f/(2.0f+numFaces));
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, r, VERT_getCo(e->v0, curLvl));
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, VERT_getCo(e->v1, curLvl));
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, 0.5f);
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, co, q);
|
||||||
|
ss->meshIFC.vertDataSub(ss->meshData, r, q);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, sharpness);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, co, r);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (_edge_isBoundary(e)) {
|
if (_edge_isBoundary(e)) {
|
||||||
ss->meshIFC.vertDataCopy(ss->meshData, co, VERT_getCo(e->v0, curLvl));
|
ss->meshIFC.vertDataCopy(ss->meshData, co, VERT_getCo(e->v0, curLvl));
|
||||||
ss->meshIFC.vertDataAdd(ss->meshData, co, VERT_getCo(e->v1, curLvl));
|
ss->meshIFC.vertDataAdd(ss->meshData, co, VERT_getCo(e->v1, curLvl));
|
||||||
@ -1124,13 +1164,95 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
|
|||||||
}
|
}
|
||||||
ss->meshIFC.vertDataMulN(ss->meshData, co, 1.0f/(2.0f+numFaces));
|
ss->meshIFC.vertDataMulN(ss->meshData, co, 1.0f/(2.0f+numFaces));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
e->flags = 0;
|
||||||
}
|
}
|
||||||
for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) {
|
for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) {
|
||||||
CCGVert *v = effectedV[ptrIdx];
|
CCGVert *v = effectedV[ptrIdx];
|
||||||
void *co = VERT_getCo(v, curLvl);
|
void *co = VERT_getCo(v, curLvl);
|
||||||
void *nCo = VERT_getCo(v, nextLvl);
|
void *nCo = VERT_getCo(v, nextLvl);
|
||||||
v->flags = 0;
|
|
||||||
|
|
||||||
|
#ifdef USE_CREASING
|
||||||
|
int sharpCount = 0;
|
||||||
|
float avgSharpness = 0.0;
|
||||||
|
CCGVert *sharpV0 = NULL, *sharpV1 = NULL;
|
||||||
|
|
||||||
|
for (i=0; i<v->numEdges; i++) {
|
||||||
|
CCGEdge *e = v->edges[i];
|
||||||
|
float sharpness = EDGE_getSharpness(e, curLvl, ss);
|
||||||
|
|
||||||
|
if (sharpness!=0.0f) {
|
||||||
|
sharpCount++;
|
||||||
|
avgSharpness += sharpness;
|
||||||
|
|
||||||
|
if (!sharpV0) {
|
||||||
|
sharpV0 = _edge_getOtherVert(e, v);
|
||||||
|
} else if (!sharpV1) {
|
||||||
|
sharpV1 = _edge_getOtherVert(e, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
avgSharpness /= sharpCount;
|
||||||
|
if (avgSharpness>1.0) {
|
||||||
|
avgSharpness = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v->numEdges || sharpCount>2) {
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
|
} else if (_vert_isBoundary(v) && sharpCount<2) {
|
||||||
|
int numBoundary = 0;
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataZero(ss->meshData, r);
|
||||||
|
for (i=0; i<v->numEdges; i++) {
|
||||||
|
CCGEdge *e = v->edges[i];
|
||||||
|
if (_edge_isBoundary(e)) {
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, VERT_getCo(_edge_getOtherVert(e, v), curLvl));
|
||||||
|
numBoundary++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 0.75);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, 0.25f/numBoundary);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
||||||
|
} else {
|
||||||
|
int numEdges = 0, numFaces = 0;
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataZero(ss->meshData, q);
|
||||||
|
for (i=0; i<v->numFaces; i++) {
|
||||||
|
CCGFace *f = v->faces[i];
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, FACE_getCenterData(f));
|
||||||
|
numFaces++;
|
||||||
|
}
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 1.0f/numFaces);
|
||||||
|
ss->meshIFC.vertDataZero(ss->meshData, r);
|
||||||
|
for (i=0; i<v->numEdges; i++) {
|
||||||
|
CCGEdge *e = v->edges[i];
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, VERT_getCo(_edge_getOtherVert(e, v), curLvl));
|
||||||
|
numEdges++;
|
||||||
|
}
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, 1.0f/numEdges);
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, numEdges-2.0f);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, q);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 1.0f/numEdges);
|
||||||
|
|
||||||
|
if (sharpCount==2) {
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, q, co);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 6.0f);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, VERT_getCo(sharpV0, curLvl));
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, VERT_getCo(sharpV1, curLvl));
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 1/8.0f);
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataSub(ss->meshData, q, nCo);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, avgSharpness);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (!v->numEdges) {
|
if (!v->numEdges) {
|
||||||
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
} else if (_vert_isBoundary(v)) {
|
} else if (_vert_isBoundary(v)) {
|
||||||
@ -1172,6 +1294,9 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
|
|||||||
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
||||||
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 1.0f/numEdges);
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 1.0f/numEdges);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
v->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss->useAgeCounts) {
|
if (ss->useAgeCounts) {
|
||||||
@ -1302,6 +1427,50 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
|
|||||||
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
|
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
|
||||||
CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
|
CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
|
||||||
|
|
||||||
|
#ifdef USE_CREASING
|
||||||
|
float sharpness = EDGE_getSharpness(e, curLvl, ss);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, co, co0);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, co, co1);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, 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;
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, q, co0);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, co1);
|
||||||
|
|
||||||
|
for (i=0; i<e->numFaces; i++) {
|
||||||
|
CCGFace *f = e->faces[i];
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, _face_getIFCoEdge(f, e, nextLvl, fx, 1, subdivLevels, vertDataSize));
|
||||||
|
numFaces++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 1.0f/(2.0f+numFaces));
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, r, co0);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, co1);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, 0.5);
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, co, q);
|
||||||
|
ss->meshIFC.vertDataSub(ss->meshData, r, q);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, sharpness);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, co, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (_edge_isBoundary(e)) {
|
if (_edge_isBoundary(e)) {
|
||||||
for (x=0; x<edgeSize-1; x++) {
|
for (x=0; x<edgeSize-1; x++) {
|
||||||
int fx = x*2 + 1;
|
int fx = x*2 + 1;
|
||||||
@ -1333,6 +1502,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
|
|||||||
ss->meshIFC.vertDataMulN(ss->meshData, co, 1.0f/(2.0f+numFaces));
|
ss->meshIFC.vertDataMulN(ss->meshData, co, 1.0f/(2.0f+numFaces));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* exterior vertex shift
|
/* exterior vertex shift
|
||||||
@ -1345,6 +1515,88 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
|
|||||||
void *co = VERT_getCo(v, curLvl);
|
void *co = VERT_getCo(v, curLvl);
|
||||||
void *nCo = VERT_getCo(v, nextLvl);
|
void *nCo = VERT_getCo(v, nextLvl);
|
||||||
|
|
||||||
|
#ifdef USE_CREASING
|
||||||
|
int sharpCount = 0;
|
||||||
|
float avgSharpness = 0.0;
|
||||||
|
CCGEdge *sharpE0 = NULL, *sharpE1 = NULL;
|
||||||
|
|
||||||
|
for (i=0; i<v->numEdges; i++) {
|
||||||
|
CCGEdge *e = v->edges[i];
|
||||||
|
float sharpness = EDGE_getSharpness(e, curLvl, ss);
|
||||||
|
|
||||||
|
if (sharpness!=0.0f) {
|
||||||
|
sharpCount++;
|
||||||
|
avgSharpness += sharpness;
|
||||||
|
|
||||||
|
if (!sharpE0) {
|
||||||
|
sharpE0 = e;
|
||||||
|
} else if (!sharpE1) {
|
||||||
|
sharpE1 = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
avgSharpness /= sharpCount;
|
||||||
|
if (avgSharpness>1.0) {
|
||||||
|
avgSharpness = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v->numEdges || sharpCount>2) {
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
|
} else if (_vert_isBoundary(v) && sharpCount<2) {
|
||||||
|
int numBoundary = 0;
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataZero(ss->meshData, r);
|
||||||
|
for (i=0; i<v->numEdges; i++) {
|
||||||
|
CCGEdge *e = v->edges[i];
|
||||||
|
if (_edge_isBoundary(e)) {
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize));
|
||||||
|
numBoundary++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 0.75);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, 0.25f/numBoundary);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
||||||
|
} else {
|
||||||
|
int cornerIdx = (1 + (1<<(curLvl))) - 2;
|
||||||
|
int numEdges = 0, numFaces = 0;
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataZero(ss->meshData, q);
|
||||||
|
for (i=0; i<v->numFaces; i++) {
|
||||||
|
CCGFace *f = v->faces[i];
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, FACE_getIFCo(f, nextLvl, _face_getVertIndex(f,v), cornerIdx, cornerIdx));
|
||||||
|
numFaces++;
|
||||||
|
}
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 1.0f/numFaces);
|
||||||
|
ss->meshIFC.vertDataZero(ss->meshData, r);
|
||||||
|
for (i=0; i<v->numEdges; i++) {
|
||||||
|
CCGEdge *e = v->edges[i];
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, _edge_getCoVert(e, v, curLvl, 1,vertDataSize));
|
||||||
|
numEdges++;
|
||||||
|
}
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, 1.0f/numEdges);
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, numEdges-2.0f);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, q);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 1.0f/numEdges);
|
||||||
|
|
||||||
|
if (sharpCount==2) {
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, q, co);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 6.0f);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, _edge_getCoVert(sharpE0, v, curLvl, 1, vertDataSize));
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, _edge_getCoVert(sharpE1, v, curLvl, 1, vertDataSize));
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 1/8.0f);
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataSub(ss->meshData, q, nCo);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, avgSharpness);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (!v->numEdges) {
|
if (!v->numEdges) {
|
||||||
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
} else if (_vert_isBoundary(v)) {
|
} else if (_vert_isBoundary(v)) {
|
||||||
@ -1388,6 +1640,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
|
|||||||
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
||||||
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 1.0f/numEdges);
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 1.0f/numEdges);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* exterior edge interior shift
|
/* exterior edge interior shift
|
||||||
@ -1398,6 +1651,80 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
|
|||||||
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
|
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
|
||||||
CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
|
CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
|
||||||
|
|
||||||
|
#ifdef USE_CREASING
|
||||||
|
float sharpness = EDGE_getSharpness(e, curLvl, ss);
|
||||||
|
int sharpCount = 0;
|
||||||
|
float avgSharpness = 0.0;
|
||||||
|
CCGVert *sharpV0 = NULL, *sharpV1 = NULL;
|
||||||
|
|
||||||
|
if (sharpness!=0.0f) {
|
||||||
|
sharpCount = 2;
|
||||||
|
avgSharpness += 2*sharpness;
|
||||||
|
} else {
|
||||||
|
sharpCount = 0;
|
||||||
|
avgSharpness = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
avgSharpness /= sharpCount;
|
||||||
|
if (avgSharpness>1.0) {
|
||||||
|
avgSharpness = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_edge_isBoundary(e) && sharpCount<2) {
|
||||||
|
for (x=1; x<edgeSize-1; x++) {
|
||||||
|
int fx = x*2;
|
||||||
|
void *co = EDGE_getCo(e, curLvl, x);
|
||||||
|
void *nCo = EDGE_getCo(e, nextLvl, fx);
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, r, EDGE_getCo(e, curLvl, x-1));
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, EDGE_getCo(e, curLvl, x+1));
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, 0.5);
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 0.75);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, 0.25);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (x=1; x<edgeSize-1; x++) {
|
||||||
|
int fx = x*2;
|
||||||
|
void *co = EDGE_getCo(e, curLvl, x);
|
||||||
|
void *nCo = EDGE_getCo(e, nextLvl, fx);
|
||||||
|
int numFaces = 0;
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataZero(ss->meshData, q);
|
||||||
|
ss->meshIFC.vertDataZero(ss->meshData, r);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, EDGE_getCo(e, curLvl, x-1));
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, EDGE_getCo(e, curLvl, x+1));
|
||||||
|
for (i=0; i<e->numFaces; i++) {
|
||||||
|
CCGFace *f = e->faces[i];
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, _face_getIFCoEdge(f, e, nextLvl, fx-1, 1, subdivLevels, vertDataSize));
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, _face_getIFCoEdge(f, e, nextLvl, fx+1, 1, subdivLevels, vertDataSize));
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, r, _face_getIFCoEdge(f, e, curLvl, x, 1, subdivLevels, vertDataSize));
|
||||||
|
numFaces++;
|
||||||
|
}
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 1.0/(numFaces*2.0f));
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, r, 1.0/(2.0f + numFaces));
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, nCo, co);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, (float) numFaces);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, q);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, r);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 1.0f/(2+numFaces));
|
||||||
|
|
||||||
|
if (sharpCount==2) {
|
||||||
|
ss->meshIFC.vertDataCopy(ss->meshData, q, co);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 6.0f);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, EDGE_getCo(e, curLvl, x-1));
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, q, EDGE_getCo(e, curLvl, x+1));
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, 1/8.0f);
|
||||||
|
|
||||||
|
ss->meshIFC.vertDataSub(ss->meshData, q, nCo);
|
||||||
|
ss->meshIFC.vertDataMulN(ss->meshData, q, avgSharpness);
|
||||||
|
ss->meshIFC.vertDataAdd(ss->meshData, nCo, q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (_edge_isBoundary(e)) {
|
if (_edge_isBoundary(e)) {
|
||||||
for (x=1; x<edgeSize-1; x++) {
|
for (x=1; x<edgeSize-1; x++) {
|
||||||
int fx = x*2;
|
int fx = x*2;
|
||||||
@ -1440,6 +1767,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
|
|||||||
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 1.0f/(2+numFaces));
|
ss->meshIFC.vertDataMulN(ss->meshData, nCo, 1.0f/(2+numFaces));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
|
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
|
||||||
@ -1580,6 +1908,16 @@ int ccgSubSurf_getNumFaces(CCGSubSurf *ss) {
|
|||||||
return ss->fMap->numEntries;
|
return ss->fMap->numEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CCGVert *ccgSubSurf_getVert(CCGSubSurf *ss, CCGVertHDL v) {
|
||||||
|
return (CCGVert*) _ehash_lookup(ss->vMap, v);
|
||||||
|
}
|
||||||
|
CCGEdge *ccgSubSurf_getEdge(CCGSubSurf *ss, CCGEdgeHDL e) {
|
||||||
|
return (CCGEdge*) _ehash_lookup(ss->eMap, e);
|
||||||
|
}
|
||||||
|
CCGFace *ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f) {
|
||||||
|
return (CCGFace*) _ehash_lookup(ss->fMap, f);
|
||||||
|
}
|
||||||
|
|
||||||
int ccgSubSurf_getSubdivisionLevels(CCGSubSurf *ss) {
|
int ccgSubSurf_getSubdivisionLevels(CCGSubSurf *ss) {
|
||||||
return ss->subdivLevels;
|
return ss->subdivLevels;
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,7 @@ int ccgSubSurf_getEdgeLevelSize (CCGSubSurf *ss, int level);
|
|||||||
int ccgSubSurf_getGridSize (CCGSubSurf *ss);
|
int ccgSubSurf_getGridSize (CCGSubSurf *ss);
|
||||||
int ccgSubSurf_getGridLevelSize (CCGSubSurf *ss, int level);
|
int ccgSubSurf_getGridLevelSize (CCGSubSurf *ss, int level);
|
||||||
|
|
||||||
|
CCGVert* ccgSubSurf_getVert (CCGSubSurf *ss, CCGVertHDL v);
|
||||||
CCGVertHDL ccgSubSurf_getVertVertHandle (CCGSubSurf *ss, CCGVert *v);
|
CCGVertHDL ccgSubSurf_getVertVertHandle (CCGSubSurf *ss, CCGVert *v);
|
||||||
int ccgSubSurf_getVertNumFaces (CCGSubSurf *ss, CCGVert *v);
|
int ccgSubSurf_getVertNumFaces (CCGSubSurf *ss, CCGVert *v);
|
||||||
CCGFace* ccgSubSurf_getVertFace (CCGSubSurf *ss, CCGVert *v, int index);
|
CCGFace* ccgSubSurf_getVertFace (CCGSubSurf *ss, CCGVert *v, int index);
|
||||||
@ -108,6 +109,7 @@ void* ccgSubSurf_getVertUserData (CCGSubSurf *ss, CCGVert *v);
|
|||||||
void* ccgSubSurf_getVertData (CCGSubSurf *ss, CCGVert *v);
|
void* ccgSubSurf_getVertData (CCGSubSurf *ss, CCGVert *v);
|
||||||
void* ccgSubSurf_getVertLevelData (CCGSubSurf *ss, CCGVert *v, int level);
|
void* ccgSubSurf_getVertLevelData (CCGSubSurf *ss, CCGVert *v, int level);
|
||||||
|
|
||||||
|
CCGEdge* ccgSubSurf_getEdge (CCGSubSurf *ss, CCGEdgeHDL e);
|
||||||
CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle (CCGSubSurf *ss, CCGEdge *e);
|
CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle (CCGSubSurf *ss, CCGEdge *e);
|
||||||
int ccgSubSurf_getEdgeNumFaces (CCGSubSurf *ss, CCGEdge *e);
|
int ccgSubSurf_getEdgeNumFaces (CCGSubSurf *ss, CCGEdge *e);
|
||||||
CCGFace* ccgSubSurf_getEdgeFace (CCGSubSurf *ss, CCGEdge *e, int index);
|
CCGFace* ccgSubSurf_getEdgeFace (CCGSubSurf *ss, CCGEdge *e, int index);
|
||||||
@ -120,6 +122,7 @@ void* ccgSubSurf_getEdgeDataArray (CCGSubSurf *ss, CCGEdge *e);
|
|||||||
void* ccgSubSurf_getEdgeData (CCGSubSurf *ss, CCGEdge *e, int x);
|
void* ccgSubSurf_getEdgeData (CCGSubSurf *ss, CCGEdge *e, int x);
|
||||||
void* ccgSubSurf_getEdgeLevelData (CCGSubSurf *ss, CCGEdge *e, int x, int level);
|
void* ccgSubSurf_getEdgeLevelData (CCGSubSurf *ss, CCGEdge *e, int x, int level);
|
||||||
|
|
||||||
|
CCGFace* ccgSubSurf_getFace (CCGSubSurf *ss, CCGFaceHDL f);
|
||||||
CCGFaceHDL ccgSubSurf_getFaceFaceHandle (CCGSubSurf *ss, CCGFace *f);
|
CCGFaceHDL ccgSubSurf_getFaceFaceHandle (CCGSubSurf *ss, CCGFace *f);
|
||||||
int ccgSubSurf_getFaceNumVerts (CCGSubSurf *ss, CCGFace *f);
|
int ccgSubSurf_getFaceNumVerts (CCGSubSurf *ss, CCGFace *f);
|
||||||
CCGVert* ccgSubSurf_getFaceVert (CCGSubSurf *ss, CCGFace *f, int index);
|
CCGVert* ccgSubSurf_getFaceVert (CCGSubSurf *ss, CCGFace *f, int index);
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
#include "CCGSubSurf.h"
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#define USE_CREASING
|
||||||
|
|
||||||
typedef struct _SubSurf {
|
typedef struct _SubSurf {
|
||||||
CCGSubSurf *subSurf;
|
CCGSubSurf *subSurf;
|
||||||
|
|
||||||
@ -102,7 +104,7 @@ static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels) {
|
|||||||
CCGAllocatorHDL allocator;
|
CCGAllocatorHDL allocator;
|
||||||
|
|
||||||
ifc.vertUserSize = 4;
|
ifc.vertUserSize = 4;
|
||||||
ifc.edgeUserSize = 4;
|
ifc.edgeUserSize = 8;
|
||||||
ifc.faceUserSize = 4;
|
ifc.faceUserSize = 4;
|
||||||
ifc.vertDataSize= 12;
|
ifc.vertDataSize= 12;
|
||||||
ifc.vertDataZero= _subsurfNew_meshIFC_vertDataZero;
|
ifc.vertDataZero= _subsurfNew_meshIFC_vertDataZero;
|
||||||
@ -525,6 +527,8 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm, int doOptEdges) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void subSurf_sync(SubSurf *ss) {
|
static void subSurf_sync(SubSurf *ss) {
|
||||||
|
float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss->subSurf);
|
||||||
|
|
||||||
ccgSubSurf_initFullSync(ss->subSurf);
|
ccgSubSurf_initFullSync(ss->subSurf);
|
||||||
|
|
||||||
if (ss->controlType==SUBSURF_CONTROLTYPE_MESH) {
|
if (ss->controlType==SUBSURF_CONTROLTYPE_MESH) {
|
||||||
@ -543,6 +547,15 @@ static void subSurf_sync(SubSurf *ss) {
|
|||||||
MEdge *med = &ss->me->medge[i];
|
MEdge *med = &ss->me->medge[i];
|
||||||
|
|
||||||
ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2);
|
ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2);
|
||||||
|
|
||||||
|
#ifdef USE_CREASING
|
||||||
|
{
|
||||||
|
CCGEdge *e = ccgSubSurf_getEdge(ss->subSurf, (CCGEdgeHDL) i);
|
||||||
|
float *userData = ccgSubSurf_getEdgeUserData(ss->subSurf, e);
|
||||||
|
|
||||||
|
userData[1] = med->crease*creaseFactor/255.0f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i=0; i<ss->me->totface; i++) {
|
for (i=0; i<ss->me->totface; i++) {
|
||||||
@ -567,25 +580,34 @@ static void subSurf_sync(SubSurf *ss) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
EditVert *v, *fVerts[4];
|
EditVert *ev, *fVerts[4];
|
||||||
EditEdge *e;
|
EditEdge *ee;
|
||||||
EditFace *f;
|
EditFace *ef;
|
||||||
|
|
||||||
for (v=ss->em->verts.first; v; v=v->next) {
|
for (ev=ss->em->verts.first; ev; ev=ev->next) {
|
||||||
ccgSubSurf_syncVert(ss->subSurf, v, v->co);
|
ccgSubSurf_syncVert(ss->subSurf, ev, ev->co);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (e=ss->em->edges.first; e; e=e->next) {
|
for (ee=ss->em->edges.first; ee; ee=ee->next) {
|
||||||
ccgSubSurf_syncEdge(ss->subSurf, e, e->v1, e->v2);
|
ccgSubSurf_syncEdge(ss->subSurf, ee, ee->v1, ee->v2);
|
||||||
|
|
||||||
|
#ifdef USE_CREASING
|
||||||
|
{
|
||||||
|
CCGEdge *e = ccgSubSurf_getEdge(ss->subSurf, ee);
|
||||||
|
float *userData = ccgSubSurf_getEdgeUserData(ss->subSurf, e);
|
||||||
|
|
||||||
|
userData[1] = ee->crease*creaseFactor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (f=ss->em->faces.first; f; f=f->next) {
|
for (ef=ss->em->faces.first; ef; ef=ef->next) {
|
||||||
fVerts[0] = f->v1;
|
fVerts[0] = ef->v1;
|
||||||
fVerts[1] = f->v2;
|
fVerts[1] = ef->v2;
|
||||||
fVerts[2] = f->v3;
|
fVerts[2] = ef->v3;
|
||||||
fVerts[3] = f->v4;
|
fVerts[3] = ef->v4;
|
||||||
|
|
||||||
ccgSubSurf_syncFace(ss->subSurf, f, f->v4?4:3, fVerts);
|
ccgSubSurf_syncFace(ss->subSurf, ef, ef->v4?4:3, fVerts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user