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:
Diffstat (limited to 'source/blender/blenkernel/intern/CCGSubSurf_legacy.c')
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_legacy.c2456
1 files changed, 1237 insertions, 1219 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
index 2e3169ebdde..430a8ef56f5 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
@@ -19,7 +19,7 @@
*/
#include "MEM_guardedalloc.h"
-#include "BLI_sys_types.h" // for intptr_t support
+#include "BLI_sys_types.h" // for intptr_t support
#include "BLI_utildefines.h" /* for BLI_assert */
#include "BLI_math.h"
@@ -28,1250 +28,1268 @@
#include "CCGSubSurf.h"
#include "CCGSubSurf_intern.h"
-#define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize)
+#define FACE_calcIFNo(f, lvl, S, x, y, no) \
+ _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize)
/* TODO(sergey): Deduplicate the following functions/ */
static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSize)
{
- int levelBase = ccg_edgebase(lvl);
- if (v == e->v0) {
- return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
- }
- else {
- return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
- }
+ int levelBase = ccg_edgebase(lvl);
+ if (v == e->v0) {
+ return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
+ }
+ else {
+ return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
+ }
}
/* *************************************************** */
static int _edge_isBoundary(const CCGEdge *e)
{
- return e->numFaces < 2;
+ return e->numFaces < 2;
}
static int _vert_isBoundary(const CCGVert *v)
{
- int i;
- for (i = 0; i < v->numEdges; i++)
- if (_edge_isBoundary(v->edges[i]))
- return 1;
- return 0;
+ int i;
+ for (i = 0; i < v->numEdges; i++)
+ if (_edge_isBoundary(v->edges[i]))
+ return 1;
+ return 0;
}
static CCGVert *_edge_getOtherVert(CCGEdge *e, CCGVert *vQ)
{
- if (vQ == e->v0) {
- return e->v1;
- }
- else {
- return e->v0;
- }
+ if (vQ == e->v0) {
+ return e->v1;
+ }
+ else {
+ return e->v0;
+ }
}
static float *_face_getIFNoEdge(CCGFace *f,
CCGEdge *e,
int f_ed_idx,
int lvl,
- int eX, int eY,
+ int eX,
+ int eY,
int levels,
int dataSize,
int normalDataOffset)
{
- return (float *) ((byte *) ccg_face_getIFCoEdge(f, e, f_ed_idx, lvl, eX, eY, levels, dataSize) + normalDataOffset);
+ return (float *)((byte *)ccg_face_getIFCoEdge(f, e, f_ed_idx, lvl, eX, eY, levels, dataSize) +
+ normalDataOffset);
}
-static void _face_calcIFNo(CCGFace *f,
- int lvl,
- int S,
- int x, int y,
- float no[3],
- int levels,
- int dataSize)
+static void _face_calcIFNo(
+ CCGFace *f, int lvl, int S, int x, int y, float no[3], int levels, int dataSize)
{
- float *a = ccg_face_getIFCo(f, lvl, S, x + 0, y + 0, levels, dataSize);
- float *b = ccg_face_getIFCo(f, lvl, S, x + 1, y + 0, levels, dataSize);
- float *c = ccg_face_getIFCo(f, lvl, S, x + 1, y + 1, levels, dataSize);
- float *d = ccg_face_getIFCo(f, lvl, S, x + 0, y + 1, levels, dataSize);
- float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2];
- float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2];
-
- no[0] = b_dY * a_cZ - b_dZ * a_cY;
- no[1] = b_dZ * a_cX - b_dX * a_cZ;
- no[2] = b_dX * a_cY - b_dY * a_cX;
-
- Normalize(no);
+ float *a = ccg_face_getIFCo(f, lvl, S, x + 0, y + 0, levels, dataSize);
+ float *b = ccg_face_getIFCo(f, lvl, S, x + 1, y + 0, levels, dataSize);
+ float *c = ccg_face_getIFCo(f, lvl, S, x + 1, y + 1, levels, dataSize);
+ float *d = ccg_face_getIFCo(f, lvl, S, x + 0, y + 1, levels, dataSize);
+ float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2];
+ float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2];
+
+ no[0] = b_dY * a_cZ - b_dZ * a_cY;
+ no[1] = b_dZ * a_cX - b_dX * a_cZ;
+ no[2] = b_dX * a_cY - b_dY * a_cX;
+
+ Normalize(no);
}
static int VERT_seam(const CCGVert *v)
{
- return ((v->flags & Vert_eSeam) != 0);
+ return ((v->flags & Vert_eSeam) != 0);
}
static float EDGE_getSharpness(CCGEdge *e, int lvl)
{
- if (!lvl)
- return e->crease;
- else if (!e->crease)
- return 0.0f;
- else if (e->crease - lvl < 0.0f)
- return 0.0f;
- else
- return e->crease - lvl;
+ if (!lvl)
+ return e->crease;
+ else if (!e->crease)
+ return 0.0f;
+ else if (e->crease - lvl < 0.0f)
+ return 0.0f;
+ else
+ return e->crease - lvl;
}
-
-
typedef struct CCGSubSurfCalcSubdivData {
- CCGSubSurf *ss;
- CCGVert **effectedV;
- CCGEdge **effectedE;
- CCGFace **effectedF;
- int numEffectedV;
- int numEffectedE;
- int numEffectedF;
-
- int curLvl;
+ CCGSubSurf *ss;
+ CCGVert **effectedV;
+ CCGEdge **effectedE;
+ CCGFace **effectedF;
+ int numEffectedV;
+ int numEffectedE;
+ int numEffectedF;
+
+ int curLvl;
} CCGSubSurfCalcSubdivData;
static void ccgSubSurf__calcVertNormals_faces_accumulate_cb(
- void *__restrict userdata,
- const int ptrIdx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
{
- CCGSubSurfCalcSubdivData *data = userdata;
-
- CCGSubSurf *ss = data->ss;
- CCGFace *f = data->effectedF[ptrIdx];
-
- const int subdivLevels = ss->subdivLevels;
- const int lvl = ss->subdivLevels;
- const int gridSize = ccg_gridsize(lvl);
- const int normalDataOffset = ss->normalDataOffset;
- const int vertDataSize = ss->meshIFC.vertDataSize;
-
- int S, x, y;
- float no[3];
-
- 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 (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);
- }
- }
- }
- }
+ CCGSubSurfCalcSubdivData *data = userdata;
+
+ CCGSubSurf *ss = data->ss;
+ CCGFace *f = data->effectedF[ptrIdx];
+
+ const int subdivLevels = ss->subdivLevels;
+ const int lvl = ss->subdivLevels;
+ const int gridSize = ccg_gridsize(lvl);
+ const int normalDataOffset = ss->normalDataOffset;
+ const int vertDataSize = ss->meshIFC.vertDataSize;
+
+ int S, x, y;
+ float no[3];
+
+ 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 (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);
+ }
+ }
+ }
+ }
}
static void ccgSubSurf__calcVertNormals_faces_finalize_cb(
- void *__restrict userdata,
- const int ptrIdx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
{
- CCGSubSurfCalcSubdivData *data = userdata;
-
- CCGSubSurf *ss = data->ss;
- CCGFace *f = data->effectedF[ptrIdx];
-
- const int subdivLevels = ss->subdivLevels;
- const int lvl = ss->subdivLevels;
- const int gridSize = ccg_gridsize(lvl);
- const int normalDataOffset = ss->normalDataOffset;
- const int vertDataSize = ss->meshIFC.vertDataSize;
-
- 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 (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);
- Normalize(no);
- }
- }
-
- VertDataCopy((float *)((byte *)FACE_getCenterData(f) + normalDataOffset),
- FACE_getIFNo(f, lvl, S, 0, 0), ss);
-
- for (x = 1; x < gridSize - 1; x++) {
- NormCopy(FACE_getIENo(f, lvl, S, x),
- FACE_getIFNo(f, lvl, S, x, 0));
- }
- }
+ CCGSubSurfCalcSubdivData *data = userdata;
+
+ CCGSubSurf *ss = data->ss;
+ CCGFace *f = data->effectedF[ptrIdx];
+
+ const int subdivLevels = ss->subdivLevels;
+ const int lvl = ss->subdivLevels;
+ const int gridSize = ccg_gridsize(lvl);
+ const int normalDataOffset = ss->normalDataOffset;
+ const int vertDataSize = ss->meshIFC.vertDataSize;
+
+ 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 (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);
+ Normalize(no);
+ }
+ }
+
+ VertDataCopy((float *)((byte *)FACE_getCenterData(f) + normalDataOffset),
+ FACE_getIFNo(f, lvl, S, 0, 0),
+ ss);
+
+ for (x = 1; x < gridSize - 1; x++) {
+ NormCopy(FACE_getIENo(f, lvl, S, x), FACE_getIFNo(f, lvl, S, x, 0));
+ }
+ }
}
static void ccgSubSurf__calcVertNormals_edges_accumulate_cb(
- void *__restrict userdata,
- const int ptrIdx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
{
- CCGSubSurfCalcSubdivData *data = userdata;
-
- CCGSubSurf *ss = data->ss;
- CCGEdge *e = data->effectedE[ptrIdx];
-
- const int subdivLevels = ss->subdivLevels;
- const int lvl = ss->subdivLevels;
- const int edgeSize = ccg_edgesize(lvl);
- const int normalDataOffset = ss->normalDataOffset;
- const int vertDataSize = ss->meshIFC.vertDataSize;
-
- if (e->numFaces) {
- CCGFace *fLast = e->faces[e->numFaces - 1];
- int x, i;
-
- for (i = 0; i < e->numFaces - 1; i++) {
- CCGFace *f = e->faces[i];
- const int f_ed_idx = ccg_face_getEdgeIndex(f, e);
- const int f_ed_idx_last = ccg_face_getEdgeIndex(fLast, e);
-
- for (x = 1; x < edgeSize - 1; x++) {
- NormAdd(_face_getIFNoEdge(fLast, e, f_ed_idx_last, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset),
- _face_getIFNoEdge(f, e, f_ed_idx, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
- }
- }
-
- for (i = 0; i < e->numFaces - 1; i++) {
- CCGFace *f = e->faces[i];
- const int f_ed_idx = ccg_face_getEdgeIndex(f, e);
- const int f_ed_idx_last = ccg_face_getEdgeIndex(fLast, e);
-
- for (x = 1; x < edgeSize - 1; x++) {
- NormCopy(_face_getIFNoEdge(f, e, f_ed_idx, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset),
- _face_getIFNoEdge(fLast, e, f_ed_idx_last, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
- }
- }
- }
+ CCGSubSurfCalcSubdivData *data = userdata;
+
+ CCGSubSurf *ss = data->ss;
+ CCGEdge *e = data->effectedE[ptrIdx];
+
+ const int subdivLevels = ss->subdivLevels;
+ const int lvl = ss->subdivLevels;
+ const int edgeSize = ccg_edgesize(lvl);
+ const int normalDataOffset = ss->normalDataOffset;
+ const int vertDataSize = ss->meshIFC.vertDataSize;
+
+ if (e->numFaces) {
+ CCGFace *fLast = e->faces[e->numFaces - 1];
+ int x, i;
+
+ for (i = 0; i < e->numFaces - 1; i++) {
+ CCGFace *f = e->faces[i];
+ const int f_ed_idx = ccg_face_getEdgeIndex(f, e);
+ const int f_ed_idx_last = ccg_face_getEdgeIndex(fLast, e);
+
+ for (x = 1; x < edgeSize - 1; x++) {
+ NormAdd(
+ _face_getIFNoEdge(
+ fLast, e, f_ed_idx_last, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset),
+ _face_getIFNoEdge(
+ f, e, f_ed_idx, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
+ }
+ }
+
+ for (i = 0; i < e->numFaces - 1; i++) {
+ CCGFace *f = e->faces[i];
+ const int f_ed_idx = ccg_face_getEdgeIndex(f, e);
+ const int f_ed_idx_last = ccg_face_getEdgeIndex(fLast, e);
+
+ for (x = 1; x < edgeSize - 1; x++) {
+ NormCopy(
+ _face_getIFNoEdge(
+ f, e, f_ed_idx, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset),
+ _face_getIFNoEdge(
+ fLast, e, f_ed_idx_last, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
+ }
+ }
+ }
}
static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
- CCGVert **effectedV, CCGEdge **effectedE, CCGFace **effectedF,
- int numEffectedV, int numEffectedE, int numEffectedF)
+ CCGVert **effectedV,
+ CCGEdge **effectedE,
+ CCGFace **effectedF,
+ int numEffectedV,
+ int numEffectedE,
+ int numEffectedF)
{
- int i, ptrIdx;
- const int subdivLevels = ss->subdivLevels;
- const int lvl = ss->subdivLevels;
- const int edgeSize = ccg_edgesize(lvl);
- const int gridSize = ccg_gridsize(lvl);
- const int normalDataOffset = ss->normalDataOffset;
- const int vertDataSize = ss->meshIFC.vertDataSize;
-
- CCGSubSurfCalcSubdivData data = {
- .ss = ss,
- .effectedV = effectedV,
- .effectedE = effectedE,
- .effectedF = effectedF,
- .numEffectedV = numEffectedV,
- .numEffectedE = numEffectedE,
- .numEffectedF = numEffectedF,
- };
-
- {
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = CCG_TASK_LIMIT;
- BLI_task_parallel_range(0, numEffectedF,
- &data,
- ccgSubSurf__calcVertNormals_faces_accumulate_cb,
- &settings);
- }
-
- /* XXX can I reduce the number of normalisations here? */
- for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
- CCGVert *v = (CCGVert *) effectedV[ptrIdx];
- float *no = VERT_getNo(v, lvl);
-
- NormZero(no);
-
- for (i = 0; i < v->numFaces; i++) {
- CCGFace *f = v->faces[i];
- NormAdd(no, FACE_getIFNo(f, lvl, ccg_face_getVertIndex(f, v), gridSize - 1, gridSize - 1));
- }
-
- if (UNLIKELY(v->numFaces == 0)) {
- NormCopy(no, VERT_getCo(v, lvl));
- }
-
- Normalize(no);
-
- for (i = 0; i < v->numFaces; i++) {
- CCGFace *f = v->faces[i];
- NormCopy(FACE_getIFNo(f, lvl, ccg_face_getVertIndex(f, v), gridSize - 1, gridSize - 1), no);
- }
- }
-
- {
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = CCG_TASK_LIMIT;
- BLI_task_parallel_range(0, numEffectedE,
- &data,
- ccgSubSurf__calcVertNormals_edges_accumulate_cb,
- &settings);
- }
-
- {
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = CCG_TASK_LIMIT;
- BLI_task_parallel_range(0, numEffectedF,
- &data,
- ccgSubSurf__calcVertNormals_faces_finalize_cb,
- &settings);
- }
-
- for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) {
- CCGEdge *e = (CCGEdge *) effectedE[ptrIdx];
-
- if (e->numFaces) {
- CCGFace *f = e->faces[0];
- int x;
- const int f_ed_idx = ccg_face_getEdgeIndex(f, e);
-
- for (x = 0; x < edgeSize; x++)
- NormCopy(EDGE_getNo(e, lvl, x),
- _face_getIFNoEdge(f, e, f_ed_idx, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
- }
- else {
- /* set to zero here otherwise the normals are uninitialized memory
- * render: tests/animation/knight.blend with valgrind.
- * we could be more clever and interpolate vertex normals but these are
- * most likely not used so just zero out. */
- int x;
-
- for (x = 0; x < edgeSize; x++) {
- float *no = EDGE_getNo(e, lvl, x);
- NormCopy(no, EDGE_getCo(e, lvl, x));
- Normalize(no);
- }
- }
- }
+ int i, ptrIdx;
+ const int subdivLevels = ss->subdivLevels;
+ const int lvl = ss->subdivLevels;
+ const int edgeSize = ccg_edgesize(lvl);
+ const int gridSize = ccg_gridsize(lvl);
+ const int normalDataOffset = ss->normalDataOffset;
+ const int vertDataSize = ss->meshIFC.vertDataSize;
+
+ CCGSubSurfCalcSubdivData data = {
+ .ss = ss,
+ .effectedV = effectedV,
+ .effectedE = effectedE,
+ .effectedF = effectedF,
+ .numEffectedV = numEffectedV,
+ .numEffectedE = numEffectedE,
+ .numEffectedF = numEffectedF,
+ };
+
+ {
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = CCG_TASK_LIMIT;
+ BLI_task_parallel_range(
+ 0, numEffectedF, &data, ccgSubSurf__calcVertNormals_faces_accumulate_cb, &settings);
+ }
+
+ /* XXX can I reduce the number of normalisations here? */
+ for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
+ CCGVert *v = (CCGVert *)effectedV[ptrIdx];
+ float *no = VERT_getNo(v, lvl);
+
+ NormZero(no);
+
+ for (i = 0; i < v->numFaces; i++) {
+ CCGFace *f = v->faces[i];
+ NormAdd(no, FACE_getIFNo(f, lvl, ccg_face_getVertIndex(f, v), gridSize - 1, gridSize - 1));
+ }
+
+ if (UNLIKELY(v->numFaces == 0)) {
+ NormCopy(no, VERT_getCo(v, lvl));
+ }
+
+ Normalize(no);
+
+ for (i = 0; i < v->numFaces; i++) {
+ CCGFace *f = v->faces[i];
+ NormCopy(FACE_getIFNo(f, lvl, ccg_face_getVertIndex(f, v), gridSize - 1, gridSize - 1), no);
+ }
+ }
+
+ {
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = CCG_TASK_LIMIT;
+ BLI_task_parallel_range(
+ 0, numEffectedE, &data, ccgSubSurf__calcVertNormals_edges_accumulate_cb, &settings);
+ }
+
+ {
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = CCG_TASK_LIMIT;
+ BLI_task_parallel_range(
+ 0, numEffectedF, &data, ccgSubSurf__calcVertNormals_faces_finalize_cb, &settings);
+ }
+
+ for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) {
+ CCGEdge *e = (CCGEdge *)effectedE[ptrIdx];
+
+ if (e->numFaces) {
+ CCGFace *f = e->faces[0];
+ int x;
+ const int f_ed_idx = ccg_face_getEdgeIndex(f, e);
+
+ for (x = 0; x < edgeSize; x++)
+ NormCopy(EDGE_getNo(e, lvl, x),
+ _face_getIFNoEdge(
+ f, e, f_ed_idx, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset));
+ }
+ else {
+ /* set to zero here otherwise the normals are uninitialized memory
+ * render: tests/animation/knight.blend with valgrind.
+ * we could be more clever and interpolate vertex normals but these are
+ * most likely not used so just zero out. */
+ int x;
+
+ for (x = 0; x < edgeSize; x++) {
+ float *no = EDGE_getNo(e, lvl, x);
+ NormCopy(no, EDGE_getCo(e, lvl, x));
+ Normalize(no);
+ }
+ }
+ }
}
-
static void ccgSubSurf__calcSubdivLevel_interior_faces_edges_midpoints_cb(
- void *__restrict userdata,
- const int ptrIdx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
{
- CCGSubSurfCalcSubdivData *data = userdata;
-
- CCGSubSurf *ss = data->ss;
- CCGFace *f = data->effectedF[ptrIdx];
-
- const int subdivLevels = ss->subdivLevels;
- const int curLvl = data->curLvl;
- const int nextLvl = curLvl + 1;
- const int gridSize = ccg_gridsize(curLvl);
- const int vertDataSize = ss->meshIFC.vertDataSize;
-
- int S, x, y;
-
- /* interior face midpoints
- * - 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;
- const float *co0 = FACE_getIFCo(f, curLvl, S, x + 0, y + 0);
- const float *co1 = FACE_getIFCo(f, curLvl, S, x + 1, y + 0);
- const float *co2 = FACE_getIFCo(f, curLvl, S, x + 1, y + 1);
- const float *co3 = FACE_getIFCo(f, curLvl, S, x + 0, y + 1);
- float *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
-
- VertDataAvg4(co, co0, co1, co2, co3, ss);
- }
- }
- }
-
- /* interior edge midpoints
- * - old interior edge points
- * - new interior face midpoints
- */
- for (S = 0; S < f->numVerts; S++) {
- for (x = 0; x < gridSize - 1; x++) {
- int fx = x * 2 + 1;
- const float *co0 = FACE_getIECo(f, curLvl, S, x + 0);
- const float *co1 = FACE_getIECo(f, curLvl, S, x + 1);
- const float *co2 = FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 1, fx);
- const float *co3 = FACE_getIFCo(f, nextLvl, S, fx, 1);
- float *co = FACE_getIECo(f, nextLvl, S, fx);
-
- VertDataAvg4(co, co0, co1, co2, co3, ss);
- }
-
- /* interior face interior edge midpoints
- * - old interior face points
- * - 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;
- const float *co0 = FACE_getIFCo(f, curLvl, S, x, y + 0);
- const float *co1 = FACE_getIFCo(f, curLvl, S, x, y + 1);
- const float *co2 = FACE_getIFCo(f, nextLvl, S, fx - 1, fy);
- const float *co3 = FACE_getIFCo(f, nextLvl, S, fx + 1, fy);
- float *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
-
- VertDataAvg4(co, co0, co1, co2, co3, ss);
- }
- }
-
- /* horizontal */
- for (y = 1; y < gridSize - 1; y++) {
- for (x = 0; x < gridSize - 1; x++) {
- int fx = x * 2 + 1;
- int fy = y * 2;
- const float *co0 = FACE_getIFCo(f, curLvl, S, x + 0, y);
- const float *co1 = FACE_getIFCo(f, curLvl, S, x + 1, y);
- const float *co2 = FACE_getIFCo(f, nextLvl, S, fx, fy - 1);
- const float *co3 = FACE_getIFCo(f, nextLvl, S, fx, fy + 1);
- float *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
-
- VertDataAvg4(co, co0, co1, co2, co3, ss);
- }
- }
- }
+ CCGSubSurfCalcSubdivData *data = userdata;
+
+ CCGSubSurf *ss = data->ss;
+ CCGFace *f = data->effectedF[ptrIdx];
+
+ const int subdivLevels = ss->subdivLevels;
+ const int curLvl = data->curLvl;
+ const int nextLvl = curLvl + 1;
+ const int gridSize = ccg_gridsize(curLvl);
+ const int vertDataSize = ss->meshIFC.vertDataSize;
+
+ int S, x, y;
+
+ /* interior face midpoints
+ * - 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;
+ const float *co0 = FACE_getIFCo(f, curLvl, S, x + 0, y + 0);
+ const float *co1 = FACE_getIFCo(f, curLvl, S, x + 1, y + 0);
+ const float *co2 = FACE_getIFCo(f, curLvl, S, x + 1, y + 1);
+ const float *co3 = FACE_getIFCo(f, curLvl, S, x + 0, y + 1);
+ float *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
+
+ VertDataAvg4(co, co0, co1, co2, co3, ss);
+ }
+ }
+ }
+
+ /* interior edge midpoints
+ * - old interior edge points
+ * - new interior face midpoints
+ */
+ for (S = 0; S < f->numVerts; S++) {
+ for (x = 0; x < gridSize - 1; x++) {
+ int fx = x * 2 + 1;
+ const float *co0 = FACE_getIECo(f, curLvl, S, x + 0);
+ const float *co1 = FACE_getIECo(f, curLvl, S, x + 1);
+ const float *co2 = FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 1, fx);
+ const float *co3 = FACE_getIFCo(f, nextLvl, S, fx, 1);
+ float *co = FACE_getIECo(f, nextLvl, S, fx);
+
+ VertDataAvg4(co, co0, co1, co2, co3, ss);
+ }
+
+ /* interior face interior edge midpoints
+ * - old interior face points
+ * - 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;
+ const float *co0 = FACE_getIFCo(f, curLvl, S, x, y + 0);
+ const float *co1 = FACE_getIFCo(f, curLvl, S, x, y + 1);
+ const float *co2 = FACE_getIFCo(f, nextLvl, S, fx - 1, fy);
+ const float *co3 = FACE_getIFCo(f, nextLvl, S, fx + 1, fy);
+ float *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
+
+ VertDataAvg4(co, co0, co1, co2, co3, ss);
+ }
+ }
+
+ /* horizontal */
+ for (y = 1; y < gridSize - 1; y++) {
+ for (x = 0; x < gridSize - 1; x++) {
+ int fx = x * 2 + 1;
+ int fy = y * 2;
+ const float *co0 = FACE_getIFCo(f, curLvl, S, x + 0, y);
+ const float *co1 = FACE_getIFCo(f, curLvl, S, x + 1, y);
+ const float *co2 = FACE_getIFCo(f, nextLvl, S, fx, fy - 1);
+ const float *co3 = FACE_getIFCo(f, nextLvl, S, fx, fy + 1);
+ float *co = FACE_getIFCo(f, nextLvl, S, fx, fy);
+
+ VertDataAvg4(co, co0, co1, co2, co3, ss);
+ }
+ }
+ }
}
static void ccgSubSurf__calcSubdivLevel_interior_faces_edges_centerpoints_shift_cb(
- void *__restrict userdata,
- const int ptrIdx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
{
- CCGSubSurfCalcSubdivData *data = userdata;
-
- CCGSubSurf *ss = data->ss;
- CCGFace *f = data->effectedF[ptrIdx];
-
- const int subdivLevels = ss->subdivLevels;
- const int curLvl = data->curLvl;
- const int nextLvl = curLvl + 1;
- const int gridSize = ccg_gridsize(curLvl);
- const int vertDataSize = ss->meshIFC.vertDataSize;
-
- float *q_thread = alloca(vertDataSize);
- float *r_thread = alloca(vertDataSize);
-
- int S, x, y;
-
- /* interior center point shift
- * - old face center point (shifting)
- * - old interior edge points
- * - new interior face midpoints
- */
- VertDataZero(q_thread, ss);
- for (S = 0; S < f->numVerts; S++) {
- VertDataAdd(q_thread, FACE_getIFCo(f, nextLvl, S, 1, 1), ss);
- }
- VertDataMulN(q_thread, 1.0f / f->numVerts, ss);
- VertDataZero(r_thread, ss);
- for (S = 0; S < f->numVerts; S++) {
- VertDataAdd(r_thread, FACE_getIECo(f, curLvl, S, 1), ss);
- }
- VertDataMulN(r_thread, 1.0f / f->numVerts, ss);
-
- VertDataMulN((float *)FACE_getCenterData(f), f->numVerts - 2.0f, ss);
- VertDataAdd((float *)FACE_getCenterData(f), q_thread, ss);
- VertDataAdd((float *)FACE_getCenterData(f), r_thread, ss);
- VertDataMulN((float *)FACE_getCenterData(f), 1.0f / f->numVerts, ss);
-
- for (S = 0; S < f->numVerts; S++) {
- /* interior face shift
- * - old interior face point (shifting)
- * - new interior edge midpoints
- * - 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;
- const float *co = FACE_getIFCo(f, curLvl, S, x, y);
- float *nCo = FACE_getIFCo(f, nextLvl, S, fx, fy);
-
- VertDataAvg4(q_thread,
- 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),
- ss);
-
- VertDataAvg4(r_thread,
- 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),
- ss);
-
- VertDataCopy(nCo, co, ss);
- VertDataSub(nCo, q_thread, ss);
- VertDataMulN(nCo, 0.25f, ss);
- VertDataAdd(nCo, r_thread, ss);
- }
- }
-
- /* interior edge interior shift
- * - old interior edge point (shifting)
- * - new interior edge midpoints
- * - new interior face midpoints
- */
- for (x = 1; x < gridSize - 1; x++) {
- int fx = x * 2;
- const float *co = FACE_getIECo(f, curLvl, S, x);
- float *nCo = FACE_getIECo(f, nextLvl, S, fx);
-
- VertDataAvg4(q_thread,
- 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),
- ss);
-
- VertDataAvg4(r_thread,
- 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),
- ss);
-
- VertDataCopy(nCo, co, ss);
- VertDataSub(nCo, q_thread, ss);
- VertDataMulN(nCo, 0.25f, ss);
- VertDataAdd(nCo, r_thread, ss);
- }
- }
+ CCGSubSurfCalcSubdivData *data = userdata;
+
+ CCGSubSurf *ss = data->ss;
+ CCGFace *f = data->effectedF[ptrIdx];
+
+ const int subdivLevels = ss->subdivLevels;
+ const int curLvl = data->curLvl;
+ const int nextLvl = curLvl + 1;
+ const int gridSize = ccg_gridsize(curLvl);
+ const int vertDataSize = ss->meshIFC.vertDataSize;
+
+ float *q_thread = alloca(vertDataSize);
+ float *r_thread = alloca(vertDataSize);
+
+ int S, x, y;
+
+ /* interior center point shift
+ * - old face center point (shifting)
+ * - old interior edge points
+ * - new interior face midpoints
+ */
+ VertDataZero(q_thread, ss);
+ for (S = 0; S < f->numVerts; S++) {
+ VertDataAdd(q_thread, FACE_getIFCo(f, nextLvl, S, 1, 1), ss);
+ }
+ VertDataMulN(q_thread, 1.0f / f->numVerts, ss);
+ VertDataZero(r_thread, ss);
+ for (S = 0; S < f->numVerts; S++) {
+ VertDataAdd(r_thread, FACE_getIECo(f, curLvl, S, 1), ss);
+ }
+ VertDataMulN(r_thread, 1.0f / f->numVerts, ss);
+
+ VertDataMulN((float *)FACE_getCenterData(f), f->numVerts - 2.0f, ss);
+ VertDataAdd((float *)FACE_getCenterData(f), q_thread, ss);
+ VertDataAdd((float *)FACE_getCenterData(f), r_thread, ss);
+ VertDataMulN((float *)FACE_getCenterData(f), 1.0f / f->numVerts, ss);
+
+ for (S = 0; S < f->numVerts; S++) {
+ /* interior face shift
+ * - old interior face point (shifting)
+ * - new interior edge midpoints
+ * - 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;
+ const float *co = FACE_getIFCo(f, curLvl, S, x, y);
+ float *nCo = FACE_getIFCo(f, nextLvl, S, fx, fy);
+
+ VertDataAvg4(q_thread,
+ 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),
+ ss);
+
+ VertDataAvg4(r_thread,
+ 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),
+ ss);
+
+ VertDataCopy(nCo, co, ss);
+ VertDataSub(nCo, q_thread, ss);
+ VertDataMulN(nCo, 0.25f, ss);
+ VertDataAdd(nCo, r_thread, ss);
+ }
+ }
+
+ /* interior edge interior shift
+ * - old interior edge point (shifting)
+ * - new interior edge midpoints
+ * - new interior face midpoints
+ */
+ for (x = 1; x < gridSize - 1; x++) {
+ int fx = x * 2;
+ const float *co = FACE_getIECo(f, curLvl, S, x);
+ float *nCo = FACE_getIECo(f, nextLvl, S, fx);
+
+ VertDataAvg4(q_thread,
+ 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),
+ ss);
+
+ VertDataAvg4(r_thread,
+ 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),
+ ss);
+
+ VertDataCopy(nCo, co, ss);
+ VertDataSub(nCo, q_thread, ss);
+ VertDataMulN(nCo, 0.25f, ss);
+ VertDataAdd(nCo, r_thread, ss);
+ }
+ }
}
static void ccgSubSurf__calcSubdivLevel_verts_copydata_cb(
- void *__restrict userdata,
- const int ptrIdx,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+ void *__restrict userdata, const int ptrIdx, const ParallelRangeTLS *__restrict UNUSED(tls))
{
- CCGSubSurfCalcSubdivData *data = userdata;
-
- CCGSubSurf *ss = data->ss;
- CCGFace *f = data->effectedF[ptrIdx];
-
- const int subdivLevels = ss->subdivLevels;
- const int nextLvl = data->curLvl + 1;
- const int gridSize = ccg_gridsize(nextLvl);
- const int cornerIdx = gridSize - 1;
- const int vertDataSize = ss->meshIFC.vertDataSize;
-
- 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];
-
- VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), (float *)FACE_getCenterData(f), ss);
- VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), (float *)FACE_getCenterData(f), ss);
- VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], nextLvl), ss);
- VertDataCopy(FACE_getIECo(f, nextLvl, S, cornerIdx), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, cornerIdx), ss);
- for (x = 1; x < gridSize - 1; x++) {
- float *co = FACE_getIECo(f, nextLvl, S, x);
- VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, 0), co, ss);
- VertDataCopy(FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 0, x), co, ss);
- }
- for (x = 0; x < gridSize - 1; x++) {
- int eI = gridSize - 1 - x;
- VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize), ss);
- VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize), ss);
- }
- }
+ CCGSubSurfCalcSubdivData *data = userdata;
+
+ CCGSubSurf *ss = data->ss;
+ CCGFace *f = data->effectedF[ptrIdx];
+
+ const int subdivLevels = ss->subdivLevels;
+ const int nextLvl = data->curLvl + 1;
+ const int gridSize = ccg_gridsize(nextLvl);
+ const int cornerIdx = gridSize - 1;
+ const int vertDataSize = ss->meshIFC.vertDataSize;
+
+ 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];
+
+ VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), (float *)FACE_getCenterData(f), ss);
+ VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), (float *)FACE_getCenterData(f), ss);
+ VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, cornerIdx),
+ VERT_getCo(FACE_getVerts(f)[S], nextLvl),
+ ss);
+ VertDataCopy(FACE_getIECo(f, nextLvl, S, cornerIdx),
+ EDGE_getCo(FACE_getEdges(f)[S], nextLvl, cornerIdx),
+ ss);
+ for (x = 1; x < gridSize - 1; x++) {
+ float *co = FACE_getIECo(f, nextLvl, S, x);
+ VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, 0), co, ss);
+ VertDataCopy(FACE_getIFCo(f, nextLvl, (S + 1) % f->numVerts, 0, x), co, ss);
+ }
+ for (x = 0; x < gridSize - 1; x++) {
+ int eI = gridSize - 1 - x;
+ VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, x),
+ _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize),
+ ss);
+ VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, cornerIdx),
+ _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, eI, vertDataSize),
+ ss);
+ }
+ }
}
-static void ccgSubSurf__calcSubdivLevel(
- CCGSubSurf *ss,
- CCGVert **effectedV, CCGEdge **effectedE, CCGFace **effectedF,
- const int numEffectedV, const int numEffectedE, const int numEffectedF, const int curLvl)
+static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
+ CCGVert **effectedV,
+ CCGEdge **effectedE,
+ CCGFace **effectedF,
+ const int numEffectedV,
+ const int numEffectedE,
+ const int numEffectedF,
+ const int curLvl)
{
- const int subdivLevels = ss->subdivLevels;
- const int nextLvl = curLvl + 1;
- int edgeSize = ccg_edgesize(curLvl);
- int ptrIdx, i;
- const int vertDataSize = ss->meshIFC.vertDataSize;
- float *q = ss->q, *r = ss->r;
-
- CCGSubSurfCalcSubdivData data = {
- .ss = ss,
- .effectedV = effectedV,
- .effectedE = effectedE,
- .effectedF = effectedF,
- .numEffectedV = numEffectedV,
- .numEffectedE = numEffectedE,
- .numEffectedF = numEffectedF,
- .curLvl = curLvl,
- };
-
- {
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = CCG_TASK_LIMIT;
- BLI_task_parallel_range(0, numEffectedF,
- &data,
- ccgSubSurf__calcSubdivLevel_interior_faces_edges_midpoints_cb,
- &settings);
- }
-
- /* exterior edge midpoints
- * - old exterior edge points
- * - new interior face midpoints
- */
- /* Not worth parallelizing. */
- 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.0f) {
- for (x = 0; x < edgeSize - 1; x++) {
- int fx = x * 2 + 1;
- const float *co0 = EDGE_getCo(e, curLvl, x + 0);
- const float *co1 = EDGE_getCo(e, curLvl, x + 1);
- float *co = EDGE_getCo(e, nextLvl, fx);
-
- VertDataCopy(co, co0, ss);
- VertDataAdd(co, co1, ss);
- VertDataMulN(co, 0.5f, ss);
- }
- }
- else {
- for (x = 0; x < edgeSize - 1; x++) {
- int fx = x * 2 + 1;
- const float *co0 = EDGE_getCo(e, curLvl, x + 0);
- const float *co1 = EDGE_getCo(e, curLvl, x + 1);
- float *co = EDGE_getCo(e, nextLvl, fx);
- int numFaces = 0;
-
- VertDataCopy(q, co0, ss);
- VertDataAdd(q, co1, ss);
-
- for (j = 0; j < e->numFaces; j++) {
- CCGFace *f = e->faces[j];
- const int f_ed_idx = ccg_face_getEdgeIndex(f, e);
- VertDataAdd(q, ccg_face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx, 1, subdivLevels, vertDataSize), ss);
- numFaces++;
- }
-
- VertDataMulN(q, 1.0f / (2.0f + numFaces), ss);
-
- VertDataCopy(r, co0, ss);
- VertDataAdd(r, co1, ss);
- VertDataMulN(r, 0.5f, ss);
-
- VertDataCopy(co, q, ss);
- VertDataSub(r, q, ss);
- VertDataMulN(r, sharpness, ss);
- VertDataAdd(co, r, ss);
- }
- }
- }
-
- /* exterior vertex shift
- * - old vertex points (shifting)
- * - old exterior edge points
- * - new interior face midpoints
- */
- /* Not worth parallelizing. */
- for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
- CCGVert *v = (CCGVert *) effectedV[ptrIdx];
- const float *co = VERT_getCo(v, curLvl);
- float *nCo = VERT_getCo(v, nextLvl);
- int sharpCount = 0, allSharp = 1;
- float avgSharpness = 0.0;
- int j, seam = VERT_seam(v), seamEdges = 0;
-
- for (j = 0; j < v->numEdges; j++) {
- CCGEdge *e = v->edges[j];
- float sharpness = EDGE_getSharpness(e, curLvl);
-
- if (seam && _edge_isBoundary(e))
- seamEdges++;
-
- if (sharpness != 0.0f) {
- sharpCount++;
- avgSharpness += sharpness;
- }
- else {
- allSharp = 0;
- }
- }
-
- if (sharpCount) {
- avgSharpness /= sharpCount;
- if (avgSharpness > 1.0f) {
- avgSharpness = 1.0f;
- }
- }
-
- if (seamEdges < 2 || seamEdges != v->numEdges)
- seam = 0;
-
- if (!v->numEdges || ss->meshIFC.simpleSubdiv) {
- VertDataCopy(nCo, co, ss);
- }
- else if (_vert_isBoundary(v)) {
- int numBoundary = 0;
-
- VertDataZero(r, ss);
- 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), ss);
- numBoundary++;
- }
- }
-
- VertDataCopy(nCo, co, ss);
- VertDataMulN(nCo, 0.75f, ss);
- VertDataMulN(r, 0.25f / numBoundary, ss);
- VertDataAdd(nCo, r, ss);
- }
- else {
- const int cornerIdx = (1 + (1 << (curLvl))) - 2;
- int numEdges = 0, numFaces = 0;
-
- VertDataZero(q, ss);
- for (j = 0; j < v->numFaces; j++) {
- CCGFace *f = v->faces[j];
- VertDataAdd(q, FACE_getIFCo(f, nextLvl, ccg_face_getVertIndex(f, v), cornerIdx, cornerIdx), ss);
- numFaces++;
- }
- VertDataMulN(q, 1.0f / numFaces, ss);
- VertDataZero(r, ss);
- for (j = 0; j < v->numEdges; j++) {
- CCGEdge *e = v->edges[j];
- VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
- numEdges++;
- }
- VertDataMulN(r, 1.0f / numEdges, ss);
-
- VertDataCopy(nCo, co, ss);
- VertDataMulN(nCo, numEdges - 2.0f, ss);
- VertDataAdd(nCo, q, ss);
- VertDataAdd(nCo, r, ss);
- VertDataMulN(nCo, 1.0f / numEdges, ss);
- }
-
- if ((sharpCount > 1 && v->numFaces) || seam) {
- VertDataZero(q, ss);
-
- if (seam) {
- avgSharpness = 1.0f;
- sharpCount = seamEdges;
- allSharp = 1;
- }
-
- for (j = 0; j < v->numEdges; j++) {
- CCGEdge *e = v->edges[j];
- float sharpness = EDGE_getSharpness(e, curLvl);
-
- if (seam) {
- if (_edge_isBoundary(e))
- VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
- }
- else if (sharpness != 0.0f) {
- VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
- }
- }
-
- VertDataMulN(q, (float) 1 / sharpCount, ss);
-
- if (sharpCount != 2 || allSharp) {
- /* q = q + (co - q) * avgSharpness */
- VertDataCopy(r, co, ss);
- VertDataSub(r, q, ss);
- VertDataMulN(r, avgSharpness, ss);
- VertDataAdd(q, r, ss);
- }
-
- /* r = co * 0.75 + q * 0.25 */
- VertDataCopy(r, co, ss);
- VertDataMulN(r, 0.75f, ss);
- VertDataMulN(q, 0.25f, ss);
- VertDataAdd(r, q, ss);
-
- /* nCo = nCo + (r - nCo) * avgSharpness */
- VertDataSub(r, nCo, ss);
- VertDataMulN(r, avgSharpness, ss);
- VertDataAdd(nCo, r, ss);
- }
- }
-
- /* exterior edge interior shift
- * - old exterior edge midpoints (shifting)
- * - old exterior edge midpoints
- * - new interior face midpoints
- */
- /* Not worth parallelizing. */
- for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) {
- CCGEdge *e = (CCGEdge *) effectedE[ptrIdx];
- float sharpness = EDGE_getSharpness(e, curLvl);
- int sharpCount = 0;
- float avgSharpness = 0.0;
- int x, j;
-
- if (sharpness != 0.0f) {
- sharpCount = 2;
- avgSharpness += sharpness;
-
- if (avgSharpness > 1.0f) {
- avgSharpness = 1.0f;
- }
- }
- else {
- sharpCount = 0;
- avgSharpness = 0;
- }
-
- if (_edge_isBoundary(e)) {
- for (x = 1; x < edgeSize - 1; x++) {
- int fx = x * 2;
- const float *co = EDGE_getCo(e, curLvl, x);
- float *nCo = EDGE_getCo(e, nextLvl, fx);
-
- /* Average previous level's endpoints */
- VertDataCopy(r, EDGE_getCo(e, curLvl, x - 1), ss);
- VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1), ss);
- VertDataMulN(r, 0.5f, ss);
-
- /* nCo = nCo * 0.75 + r * 0.25 */
- VertDataCopy(nCo, co, ss);
- VertDataMulN(nCo, 0.75f, ss);
- VertDataMulN(r, 0.25f, ss);
- VertDataAdd(nCo, r, ss);
- }
- }
- else {
- for (x = 1; x < edgeSize - 1; x++) {
- int fx = x * 2;
- const float *co = EDGE_getCo(e, curLvl, x);
- float *nCo = EDGE_getCo(e, nextLvl, fx);
- int numFaces = 0;
-
- VertDataZero(q, ss);
- VertDataZero(r, ss);
- VertDataAdd(r, EDGE_getCo(e, curLvl, x - 1), ss);
- VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1), ss);
- for (j = 0; j < e->numFaces; j++) {
- CCGFace *f = e->faces[j];
- int f_ed_idx = ccg_face_getEdgeIndex(f, e);
- VertDataAdd(q, ccg_face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx - 1, 1, subdivLevels, vertDataSize), ss);
- VertDataAdd(q, ccg_face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx + 1, 1, subdivLevels, vertDataSize), ss);
-
- VertDataAdd(r, ccg_face_getIFCoEdge(f, e, f_ed_idx, curLvl, x, 1, subdivLevels, vertDataSize), ss);
- numFaces++;
- }
- VertDataMulN(q, 1.0f / (numFaces * 2.0f), ss);
- VertDataMulN(r, 1.0f / (2.0f + numFaces), ss);
-
- VertDataCopy(nCo, co, ss);
- VertDataMulN(nCo, (float) numFaces, ss);
- VertDataAdd(nCo, q, ss);
- VertDataAdd(nCo, r, ss);
- VertDataMulN(nCo, 1.0f / (2 + numFaces), ss);
-
- if (sharpCount == 2) {
- VertDataCopy(q, co, ss);
- VertDataMulN(q, 6.0f, ss);
- VertDataAdd(q, EDGE_getCo(e, curLvl, x - 1), ss);
- VertDataAdd(q, EDGE_getCo(e, curLvl, x + 1), ss);
- VertDataMulN(q, 1 / 8.0f, ss);
-
- VertDataSub(q, nCo, ss);
- VertDataMulN(q, avgSharpness, ss);
- VertDataAdd(nCo, q, ss);
- }
- }
- }
- }
-
- {
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = CCG_TASK_LIMIT;
- BLI_task_parallel_range(0, numEffectedF,
- &data,
- ccgSubSurf__calcSubdivLevel_interior_faces_edges_centerpoints_shift_cb,
- &settings);
- }
-
- /* copy down */
- edgeSize = ccg_edgesize(nextLvl);
-
- /* Not worth parallelizing. */
- for (i = 0; i < numEffectedE; i++) {
- CCGEdge *e = effectedE[i];
- VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl), ss);
- VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize - 1), VERT_getCo(e->v1, nextLvl), ss);
- }
-
- {
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = CCG_TASK_LIMIT;
- BLI_task_parallel_range(0, numEffectedF,
- &data,
- ccgSubSurf__calcSubdivLevel_verts_copydata_cb,
- &settings);
- }
+ const int subdivLevels = ss->subdivLevels;
+ const int nextLvl = curLvl + 1;
+ int edgeSize = ccg_edgesize(curLvl);
+ int ptrIdx, i;
+ const int vertDataSize = ss->meshIFC.vertDataSize;
+ float *q = ss->q, *r = ss->r;
+
+ CCGSubSurfCalcSubdivData data = {
+ .ss = ss,
+ .effectedV = effectedV,
+ .effectedE = effectedE,
+ .effectedF = effectedF,
+ .numEffectedV = numEffectedV,
+ .numEffectedE = numEffectedE,
+ .numEffectedF = numEffectedF,
+ .curLvl = curLvl,
+ };
+
+ {
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = CCG_TASK_LIMIT;
+ BLI_task_parallel_range(0,
+ numEffectedF,
+ &data,
+ ccgSubSurf__calcSubdivLevel_interior_faces_edges_midpoints_cb,
+ &settings);
+ }
+
+ /* exterior edge midpoints
+ * - old exterior edge points
+ * - new interior face midpoints
+ */
+ /* Not worth parallelizing. */
+ 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.0f) {
+ for (x = 0; x < edgeSize - 1; x++) {
+ int fx = x * 2 + 1;
+ const float *co0 = EDGE_getCo(e, curLvl, x + 0);
+ const float *co1 = EDGE_getCo(e, curLvl, x + 1);
+ float *co = EDGE_getCo(e, nextLvl, fx);
+
+ VertDataCopy(co, co0, ss);
+ VertDataAdd(co, co1, ss);
+ VertDataMulN(co, 0.5f, ss);
+ }
+ }
+ else {
+ for (x = 0; x < edgeSize - 1; x++) {
+ int fx = x * 2 + 1;
+ const float *co0 = EDGE_getCo(e, curLvl, x + 0);
+ const float *co1 = EDGE_getCo(e, curLvl, x + 1);
+ float *co = EDGE_getCo(e, nextLvl, fx);
+ int numFaces = 0;
+
+ VertDataCopy(q, co0, ss);
+ VertDataAdd(q, co1, ss);
+
+ for (j = 0; j < e->numFaces; j++) {
+ CCGFace *f = e->faces[j];
+ const int f_ed_idx = ccg_face_getEdgeIndex(f, e);
+ VertDataAdd(
+ q,
+ ccg_face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx, 1, subdivLevels, vertDataSize),
+ ss);
+ numFaces++;
+ }
+
+ VertDataMulN(q, 1.0f / (2.0f + numFaces), ss);
+
+ VertDataCopy(r, co0, ss);
+ VertDataAdd(r, co1, ss);
+ VertDataMulN(r, 0.5f, ss);
+
+ VertDataCopy(co, q, ss);
+ VertDataSub(r, q, ss);
+ VertDataMulN(r, sharpness, ss);
+ VertDataAdd(co, r, ss);
+ }
+ }
+ }
+
+ /* exterior vertex shift
+ * - old vertex points (shifting)
+ * - old exterior edge points
+ * - new interior face midpoints
+ */
+ /* Not worth parallelizing. */
+ for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
+ CCGVert *v = (CCGVert *)effectedV[ptrIdx];
+ const float *co = VERT_getCo(v, curLvl);
+ float *nCo = VERT_getCo(v, nextLvl);
+ int sharpCount = 0, allSharp = 1;
+ float avgSharpness = 0.0;
+ int j, seam = VERT_seam(v), seamEdges = 0;
+
+ for (j = 0; j < v->numEdges; j++) {
+ CCGEdge *e = v->edges[j];
+ float sharpness = EDGE_getSharpness(e, curLvl);
+
+ if (seam && _edge_isBoundary(e))
+ seamEdges++;
+
+ if (sharpness != 0.0f) {
+ sharpCount++;
+ avgSharpness += sharpness;
+ }
+ else {
+ allSharp = 0;
+ }
+ }
+
+ if (sharpCount) {
+ avgSharpness /= sharpCount;
+ if (avgSharpness > 1.0f) {
+ avgSharpness = 1.0f;
+ }
+ }
+
+ if (seamEdges < 2 || seamEdges != v->numEdges)
+ seam = 0;
+
+ if (!v->numEdges || ss->meshIFC.simpleSubdiv) {
+ VertDataCopy(nCo, co, ss);
+ }
+ else if (_vert_isBoundary(v)) {
+ int numBoundary = 0;
+
+ VertDataZero(r, ss);
+ 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), ss);
+ numBoundary++;
+ }
+ }
+
+ VertDataCopy(nCo, co, ss);
+ VertDataMulN(nCo, 0.75f, ss);
+ VertDataMulN(r, 0.25f / numBoundary, ss);
+ VertDataAdd(nCo, r, ss);
+ }
+ else {
+ const int cornerIdx = (1 + (1 << (curLvl))) - 2;
+ int numEdges = 0, numFaces = 0;
+
+ VertDataZero(q, ss);
+ for (j = 0; j < v->numFaces; j++) {
+ CCGFace *f = v->faces[j];
+ VertDataAdd(
+ q, FACE_getIFCo(f, nextLvl, ccg_face_getVertIndex(f, v), cornerIdx, cornerIdx), ss);
+ numFaces++;
+ }
+ VertDataMulN(q, 1.0f / numFaces, ss);
+ VertDataZero(r, ss);
+ for (j = 0; j < v->numEdges; j++) {
+ CCGEdge *e = v->edges[j];
+ VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
+ numEdges++;
+ }
+ VertDataMulN(r, 1.0f / numEdges, ss);
+
+ VertDataCopy(nCo, co, ss);
+ VertDataMulN(nCo, numEdges - 2.0f, ss);
+ VertDataAdd(nCo, q, ss);
+ VertDataAdd(nCo, r, ss);
+ VertDataMulN(nCo, 1.0f / numEdges, ss);
+ }
+
+ if ((sharpCount > 1 && v->numFaces) || seam) {
+ VertDataZero(q, ss);
+
+ if (seam) {
+ avgSharpness = 1.0f;
+ sharpCount = seamEdges;
+ allSharp = 1;
+ }
+
+ for (j = 0; j < v->numEdges; j++) {
+ CCGEdge *e = v->edges[j];
+ float sharpness = EDGE_getSharpness(e, curLvl);
+
+ if (seam) {
+ if (_edge_isBoundary(e))
+ VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
+ }
+ else if (sharpness != 0.0f) {
+ VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize), ss);
+ }
+ }
+
+ VertDataMulN(q, (float)1 / sharpCount, ss);
+
+ if (sharpCount != 2 || allSharp) {
+ /* q = q + (co - q) * avgSharpness */
+ VertDataCopy(r, co, ss);
+ VertDataSub(r, q, ss);
+ VertDataMulN(r, avgSharpness, ss);
+ VertDataAdd(q, r, ss);
+ }
+
+ /* r = co * 0.75 + q * 0.25 */
+ VertDataCopy(r, co, ss);
+ VertDataMulN(r, 0.75f, ss);
+ VertDataMulN(q, 0.25f, ss);
+ VertDataAdd(r, q, ss);
+
+ /* nCo = nCo + (r - nCo) * avgSharpness */
+ VertDataSub(r, nCo, ss);
+ VertDataMulN(r, avgSharpness, ss);
+ VertDataAdd(nCo, r, ss);
+ }
+ }
+
+ /* exterior edge interior shift
+ * - old exterior edge midpoints (shifting)
+ * - old exterior edge midpoints
+ * - new interior face midpoints
+ */
+ /* Not worth parallelizing. */
+ for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) {
+ CCGEdge *e = (CCGEdge *)effectedE[ptrIdx];
+ float sharpness = EDGE_getSharpness(e, curLvl);
+ int sharpCount = 0;
+ float avgSharpness = 0.0;
+ int x, j;
+
+ if (sharpness != 0.0f) {
+ sharpCount = 2;
+ avgSharpness += sharpness;
+
+ if (avgSharpness > 1.0f) {
+ avgSharpness = 1.0f;
+ }
+ }
+ else {
+ sharpCount = 0;
+ avgSharpness = 0;
+ }
+
+ if (_edge_isBoundary(e)) {
+ for (x = 1; x < edgeSize - 1; x++) {
+ int fx = x * 2;
+ const float *co = EDGE_getCo(e, curLvl, x);
+ float *nCo = EDGE_getCo(e, nextLvl, fx);
+
+ /* Average previous level's endpoints */
+ VertDataCopy(r, EDGE_getCo(e, curLvl, x - 1), ss);
+ VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1), ss);
+ VertDataMulN(r, 0.5f, ss);
+
+ /* nCo = nCo * 0.75 + r * 0.25 */
+ VertDataCopy(nCo, co, ss);
+ VertDataMulN(nCo, 0.75f, ss);
+ VertDataMulN(r, 0.25f, ss);
+ VertDataAdd(nCo, r, ss);
+ }
+ }
+ else {
+ for (x = 1; x < edgeSize - 1; x++) {
+ int fx = x * 2;
+ const float *co = EDGE_getCo(e, curLvl, x);
+ float *nCo = EDGE_getCo(e, nextLvl, fx);
+ int numFaces = 0;
+
+ VertDataZero(q, ss);
+ VertDataZero(r, ss);
+ VertDataAdd(r, EDGE_getCo(e, curLvl, x - 1), ss);
+ VertDataAdd(r, EDGE_getCo(e, curLvl, x + 1), ss);
+ for (j = 0; j < e->numFaces; j++) {
+ CCGFace *f = e->faces[j];
+ int f_ed_idx = ccg_face_getEdgeIndex(f, e);
+ VertDataAdd(
+ q,
+ ccg_face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx - 1, 1, subdivLevels, vertDataSize),
+ ss);
+ VertDataAdd(
+ q,
+ ccg_face_getIFCoEdge(f, e, f_ed_idx, nextLvl, fx + 1, 1, subdivLevels, vertDataSize),
+ ss);
+
+ VertDataAdd(
+ r,
+ ccg_face_getIFCoEdge(f, e, f_ed_idx, curLvl, x, 1, subdivLevels, vertDataSize),
+ ss);
+ numFaces++;
+ }
+ VertDataMulN(q, 1.0f / (numFaces * 2.0f), ss);
+ VertDataMulN(r, 1.0f / (2.0f + numFaces), ss);
+
+ VertDataCopy(nCo, co, ss);
+ VertDataMulN(nCo, (float)numFaces, ss);
+ VertDataAdd(nCo, q, ss);
+ VertDataAdd(nCo, r, ss);
+ VertDataMulN(nCo, 1.0f / (2 + numFaces), ss);
+
+ if (sharpCount == 2) {
+ VertDataCopy(q, co, ss);
+ VertDataMulN(q, 6.0f, ss);
+ VertDataAdd(q, EDGE_getCo(e, curLvl, x - 1), ss);
+ VertDataAdd(q, EDGE_getCo(e, curLvl, x + 1), ss);
+ VertDataMulN(q, 1 / 8.0f, ss);
+
+ VertDataSub(q, nCo, ss);
+ VertDataMulN(q, avgSharpness, ss);
+ VertDataAdd(nCo, q, ss);
+ }
+ }
+ }
+ }
+
+ {
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = CCG_TASK_LIMIT;
+ BLI_task_parallel_range(0,
+ numEffectedF,
+ &data,
+ ccgSubSurf__calcSubdivLevel_interior_faces_edges_centerpoints_shift_cb,
+ &settings);
+ }
+
+ /* copy down */
+ edgeSize = ccg_edgesize(nextLvl);
+
+ /* Not worth parallelizing. */
+ for (i = 0; i < numEffectedE; i++) {
+ CCGEdge *e = effectedE[i];
+ VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl), ss);
+ VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize - 1), VERT_getCo(e->v1, nextLvl), ss);
+ }
+
+ {
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = CCG_TASK_LIMIT;
+ BLI_task_parallel_range(
+ 0, numEffectedF, &data, ccgSubSurf__calcSubdivLevel_verts_copydata_cb, &settings);
+ }
}
void ccgSubSurf__sync_legacy(CCGSubSurf *ss)
{
- CCGVert **effectedV;
- CCGEdge **effectedE;
- CCGFace **effectedF;
- int numEffectedV, numEffectedE, numEffectedF;
- int subdivLevels = ss->subdivLevels;
- int vertDataSize = ss->meshIFC.vertDataSize;
- int i, j, ptrIdx, S;
- int curLvl, nextLvl;
- void *q = ss->q, *r = ss->r;
-
- effectedV = MEM_mallocN(sizeof(*effectedV) * ss->vMap->numEntries, "CCGSubsurf effectedV");
- effectedE = MEM_mallocN(sizeof(*effectedE) * ss->eMap->numEntries, "CCGSubsurf effectedE");
- effectedF = MEM_mallocN(sizeof(*effectedF) * ss->fMap->numEntries, "CCGSubsurf effectedF");
- numEffectedV = numEffectedE = numEffectedF = 0;
- for (i = 0; i < ss->vMap->curSize; i++) {
- CCGVert *v = (CCGVert *) ss->vMap->buckets[i];
- for (; v; v = v->next) {
- if (v->flags & Vert_eEffected) {
- effectedV[numEffectedV++] = v;
-
- for (j = 0; j < v->numEdges; j++) {
- CCGEdge *e = v->edges[j];
- if (!(e->flags & Edge_eEffected)) {
- effectedE[numEffectedE++] = e;
- e->flags |= Edge_eEffected;
- }
- }
-
- for (j = 0; j < v->numFaces; j++) {
- CCGFace *f = v->faces[j];
- if (!(f->flags & Face_eEffected)) {
- effectedF[numEffectedF++] = f;
- f->flags |= Face_eEffected;
- }
- }
- }
- }
- }
-
- curLvl = 0;
- nextLvl = curLvl + 1;
-
- for (ptrIdx = 0; ptrIdx < numEffectedF; ptrIdx++) {
- CCGFace *f = effectedF[ptrIdx];
- void *co = FACE_getCenterData(f);
- VertDataZero(co, ss);
- for (i = 0; i < f->numVerts; i++) {
- VertDataAdd(co, VERT_getCo(FACE_getVerts(f)[i], curLvl), ss);
- }
- VertDataMulN(co, 1.0f / f->numVerts, ss);
-
- f->flags = 0;
- }
- for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) {
- CCGEdge *e = effectedE[ptrIdx];
- void *co = EDGE_getCo(e, nextLvl, 1);
- float sharpness = EDGE_getSharpness(e, curLvl);
-
- if (_edge_isBoundary(e) || sharpness >= 1.0f) {
- VertDataCopy(co, VERT_getCo(e->v0, curLvl), ss);
- VertDataAdd(co, VERT_getCo(e->v1, curLvl), ss);
- VertDataMulN(co, 0.5f, ss);
- }
- else {
- int numFaces = 0;
- VertDataCopy(q, VERT_getCo(e->v0, curLvl), ss);
- VertDataAdd(q, VERT_getCo(e->v1, curLvl), ss);
- for (i = 0; i < e->numFaces; i++) {
- CCGFace *f = e->faces[i];
- VertDataAdd(q, (float *)FACE_getCenterData(f), ss);
- numFaces++;
- }
- VertDataMulN(q, 1.0f / (2.0f + numFaces), ss);
-
- VertDataCopy(r, VERT_getCo(e->v0, curLvl), ss);
- VertDataAdd(r, VERT_getCo(e->v1, curLvl), ss);
- VertDataMulN(r, 0.5f, ss);
-
- VertDataCopy(co, q, ss);
- VertDataSub(r, q, ss);
- VertDataMulN(r, sharpness, ss);
- VertDataAdd(co, r, ss);
- }
-
- /* edge flags cleared later */
- }
- for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
- CCGVert *v = effectedV[ptrIdx];
- void *co = VERT_getCo(v, curLvl);
- void *nCo = VERT_getCo(v, nextLvl);
- int sharpCount = 0, allSharp = 1;
- float avgSharpness = 0.0;
- int seam = VERT_seam(v), seamEdges = 0;
-
- for (i = 0; i < v->numEdges; i++) {
- CCGEdge *e = v->edges[i];
- float sharpness = EDGE_getSharpness(e, curLvl);
-
- if (seam && _edge_isBoundary(e))
- seamEdges++;
-
- if (sharpness != 0.0f) {
- sharpCount++;
- avgSharpness += sharpness;
- }
- else {
- allSharp = 0;
- }
- }
-
- if (sharpCount) {
- avgSharpness /= sharpCount;
- if (avgSharpness > 1.0f) {
- avgSharpness = 1.0f;
- }
- }
-
- if (seamEdges < 2 || seamEdges != v->numEdges)
- seam = 0;
-
- if (!v->numEdges || ss->meshIFC.simpleSubdiv) {
- VertDataCopy(nCo, co, ss);
- }
- else if (_vert_isBoundary(v)) {
- int numBoundary = 0;
-
- VertDataZero(r, ss);
- for (i = 0; i < v->numEdges; i++) {
- CCGEdge *e = v->edges[i];
- if (_edge_isBoundary(e)) {
- VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl), ss);
- numBoundary++;
- }
- }
- VertDataCopy(nCo, co, ss);
- VertDataMulN(nCo, 0.75f, ss);
- VertDataMulN(r, 0.25f / numBoundary, ss);
- VertDataAdd(nCo, r, ss);
- }
- else {
- int numEdges = 0, numFaces = 0;
-
- VertDataZero(q, ss);
- for (i = 0; i < v->numFaces; i++) {
- CCGFace *f = v->faces[i];
- VertDataAdd(q, (float *)FACE_getCenterData(f), ss);
- numFaces++;
- }
- VertDataMulN(q, 1.0f / numFaces, ss);
- VertDataZero(r, ss);
- for (i = 0; i < v->numEdges; i++) {
- CCGEdge *e = v->edges[i];
- VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl), ss);
- numEdges++;
- }
- VertDataMulN(r, 1.0f / numEdges, ss);
-
- VertDataCopy(nCo, co, ss);
- VertDataMulN(nCo, numEdges - 2.0f, ss);
- VertDataAdd(nCo, q, ss);
- VertDataAdd(nCo, r, ss);
- VertDataMulN(nCo, 1.0f / numEdges, ss);
- }
-
- if (sharpCount > 1 || seam) {
- VertDataZero(q, ss);
-
- if (seam) {
- avgSharpness = 1.0f;
- sharpCount = seamEdges;
- allSharp = 1;
- }
-
- for (i = 0; i < v->numEdges; i++) {
- CCGEdge *e = v->edges[i];
- float sharpness = EDGE_getSharpness(e, curLvl);
-
- if (seam) {
- if (_edge_isBoundary(e)) {
- CCGVert *oV = _edge_getOtherVert(e, v);
- VertDataAdd(q, VERT_getCo(oV, curLvl), ss);
- }
- }
- else if (sharpness != 0.0f) {
- CCGVert *oV = _edge_getOtherVert(e, v);
- VertDataAdd(q, VERT_getCo(oV, curLvl), ss);
- }
- }
-
- VertDataMulN(q, (float) 1 / sharpCount, ss);
-
- if (sharpCount != 2 || allSharp) {
- /* q = q + (co - q) * avgSharpness */
- VertDataCopy(r, co, ss);
- VertDataSub(r, q, ss);
- VertDataMulN(r, avgSharpness, ss);
- VertDataAdd(q, r, ss);
- }
-
- /* r = co * 0.75 + q * 0.25 */
- VertDataCopy(r, co, ss);
- VertDataMulN(r, 0.75f, ss);
- VertDataMulN(q, 0.25f, ss);
- VertDataAdd(r, q, ss);
-
- /* nCo = nCo + (r - nCo) * avgSharpness */
- VertDataSub(r, nCo, ss);
- VertDataMulN(r, avgSharpness, ss);
- VertDataAdd(nCo, r, ss);
- }
-
- /* vert flags cleared later */
- }
-
- if (ss->useAgeCounts) {
- for (i = 0; i < numEffectedV; i++) {
- CCGVert *v = effectedV[i];
- byte *userData = ccgSubSurf_getVertUserData(ss, v);
- *((int *) &userData[ss->vertUserAgeOffset]) = ss->currentAge;
- }
-
- for (i = 0; i < numEffectedE; i++) {
- CCGEdge *e = effectedE[i];
- byte *userData = ccgSubSurf_getEdgeUserData(ss, e);
- *((int *) &userData[ss->edgeUserAgeOffset]) = ss->currentAge;
- }
-
- for (i = 0; i < numEffectedF; i++) {
- CCGFace *f = effectedF[i];
- byte *userData = ccgSubSurf_getFaceUserData(ss, f);
- *((int *) &userData[ss->faceUserAgeOffset]) = ss->currentAge;
- }
- }
-
- for (i = 0; i < numEffectedE; i++) {
- CCGEdge *e = effectedE[i];
- VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl), ss);
- VertDataCopy(EDGE_getCo(e, nextLvl, 2), VERT_getCo(e->v1, nextLvl), ss);
- }
- for (i = 0; i < numEffectedF; i++) {
- CCGFace *f = effectedF[i];
- for (S = 0; S < f->numVerts; S++) {
- CCGEdge *e = FACE_getEdges(f)[S];
- CCGEdge *prevE = FACE_getEdges(f)[(S + f->numVerts - 1) % f->numVerts];
-
- VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), (float *)FACE_getCenterData(f), ss);
- VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), (float *)FACE_getCenterData(f), ss);
- VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 1), VERT_getCo(FACE_getVerts(f)[S], nextLvl), ss);
- VertDataCopy(FACE_getIECo(f, nextLvl, S, 1), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, 1), ss);
-
- VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 0), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize), ss);
- VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 1), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize), ss);
- }
- }
-
- for (curLvl = 1; curLvl < subdivLevels; curLvl++)
- ccgSubSurf__calcSubdivLevel(ss,
- effectedV, effectedE, effectedF,
- numEffectedV, numEffectedE, numEffectedF, curLvl);
-
- if (ss->calcVertNormals)
- ccgSubSurf__calcVertNormals(ss,
- effectedV, effectedE, effectedF,
- numEffectedV, numEffectedE, numEffectedF);
-
- for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
- CCGVert *v = effectedV[ptrIdx];
- v->flags = 0;
- }
- for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) {
- CCGEdge *e = effectedE[ptrIdx];
- e->flags = 0;
- }
-
- MEM_freeN(effectedF);
- MEM_freeN(effectedE);
- MEM_freeN(effectedV);
+ CCGVert **effectedV;
+ CCGEdge **effectedE;
+ CCGFace **effectedF;
+ int numEffectedV, numEffectedE, numEffectedF;
+ int subdivLevels = ss->subdivLevels;
+ int vertDataSize = ss->meshIFC.vertDataSize;
+ int i, j, ptrIdx, S;
+ int curLvl, nextLvl;
+ void *q = ss->q, *r = ss->r;
+
+ effectedV = MEM_mallocN(sizeof(*effectedV) * ss->vMap->numEntries, "CCGSubsurf effectedV");
+ effectedE = MEM_mallocN(sizeof(*effectedE) * ss->eMap->numEntries, "CCGSubsurf effectedE");
+ effectedF = MEM_mallocN(sizeof(*effectedF) * ss->fMap->numEntries, "CCGSubsurf effectedF");
+ numEffectedV = numEffectedE = numEffectedF = 0;
+ for (i = 0; i < ss->vMap->curSize; i++) {
+ CCGVert *v = (CCGVert *)ss->vMap->buckets[i];
+ for (; v; v = v->next) {
+ if (v->flags & Vert_eEffected) {
+ effectedV[numEffectedV++] = v;
+
+ for (j = 0; j < v->numEdges; j++) {
+ CCGEdge *e = v->edges[j];
+ if (!(e->flags & Edge_eEffected)) {
+ effectedE[numEffectedE++] = e;
+ e->flags |= Edge_eEffected;
+ }
+ }
+
+ for (j = 0; j < v->numFaces; j++) {
+ CCGFace *f = v->faces[j];
+ if (!(f->flags & Face_eEffected)) {
+ effectedF[numEffectedF++] = f;
+ f->flags |= Face_eEffected;
+ }
+ }
+ }
+ }
+ }
+
+ curLvl = 0;
+ nextLvl = curLvl + 1;
+
+ for (ptrIdx = 0; ptrIdx < numEffectedF; ptrIdx++) {
+ CCGFace *f = effectedF[ptrIdx];
+ void *co = FACE_getCenterData(f);
+ VertDataZero(co, ss);
+ for (i = 0; i < f->numVerts; i++) {
+ VertDataAdd(co, VERT_getCo(FACE_getVerts(f)[i], curLvl), ss);
+ }
+ VertDataMulN(co, 1.0f / f->numVerts, ss);
+
+ f->flags = 0;
+ }
+ for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) {
+ CCGEdge *e = effectedE[ptrIdx];
+ void *co = EDGE_getCo(e, nextLvl, 1);
+ float sharpness = EDGE_getSharpness(e, curLvl);
+
+ if (_edge_isBoundary(e) || sharpness >= 1.0f) {
+ VertDataCopy(co, VERT_getCo(e->v0, curLvl), ss);
+ VertDataAdd(co, VERT_getCo(e->v1, curLvl), ss);
+ VertDataMulN(co, 0.5f, ss);
+ }
+ else {
+ int numFaces = 0;
+ VertDataCopy(q, VERT_getCo(e->v0, curLvl), ss);
+ VertDataAdd(q, VERT_getCo(e->v1, curLvl), ss);
+ for (i = 0; i < e->numFaces; i++) {
+ CCGFace *f = e->faces[i];
+ VertDataAdd(q, (float *)FACE_getCenterData(f), ss);
+ numFaces++;
+ }
+ VertDataMulN(q, 1.0f / (2.0f + numFaces), ss);
+
+ VertDataCopy(r, VERT_getCo(e->v0, curLvl), ss);
+ VertDataAdd(r, VERT_getCo(e->v1, curLvl), ss);
+ VertDataMulN(r, 0.5f, ss);
+
+ VertDataCopy(co, q, ss);
+ VertDataSub(r, q, ss);
+ VertDataMulN(r, sharpness, ss);
+ VertDataAdd(co, r, ss);
+ }
+
+ /* edge flags cleared later */
+ }
+ for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
+ CCGVert *v = effectedV[ptrIdx];
+ void *co = VERT_getCo(v, curLvl);
+ void *nCo = VERT_getCo(v, nextLvl);
+ int sharpCount = 0, allSharp = 1;
+ float avgSharpness = 0.0;
+ int seam = VERT_seam(v), seamEdges = 0;
+
+ for (i = 0; i < v->numEdges; i++) {
+ CCGEdge *e = v->edges[i];
+ float sharpness = EDGE_getSharpness(e, curLvl);
+
+ if (seam && _edge_isBoundary(e))
+ seamEdges++;
+
+ if (sharpness != 0.0f) {
+ sharpCount++;
+ avgSharpness += sharpness;
+ }
+ else {
+ allSharp = 0;
+ }
+ }
+
+ if (sharpCount) {
+ avgSharpness /= sharpCount;
+ if (avgSharpness > 1.0f) {
+ avgSharpness = 1.0f;
+ }
+ }
+
+ if (seamEdges < 2 || seamEdges != v->numEdges)
+ seam = 0;
+
+ if (!v->numEdges || ss->meshIFC.simpleSubdiv) {
+ VertDataCopy(nCo, co, ss);
+ }
+ else if (_vert_isBoundary(v)) {
+ int numBoundary = 0;
+
+ VertDataZero(r, ss);
+ for (i = 0; i < v->numEdges; i++) {
+ CCGEdge *e = v->edges[i];
+ if (_edge_isBoundary(e)) {
+ VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl), ss);
+ numBoundary++;
+ }
+ }
+ VertDataCopy(nCo, co, ss);
+ VertDataMulN(nCo, 0.75f, ss);
+ VertDataMulN(r, 0.25f / numBoundary, ss);
+ VertDataAdd(nCo, r, ss);
+ }
+ else {
+ int numEdges = 0, numFaces = 0;
+
+ VertDataZero(q, ss);
+ for (i = 0; i < v->numFaces; i++) {
+ CCGFace *f = v->faces[i];
+ VertDataAdd(q, (float *)FACE_getCenterData(f), ss);
+ numFaces++;
+ }
+ VertDataMulN(q, 1.0f / numFaces, ss);
+ VertDataZero(r, ss);
+ for (i = 0; i < v->numEdges; i++) {
+ CCGEdge *e = v->edges[i];
+ VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl), ss);
+ numEdges++;
+ }
+ VertDataMulN(r, 1.0f / numEdges, ss);
+
+ VertDataCopy(nCo, co, ss);
+ VertDataMulN(nCo, numEdges - 2.0f, ss);
+ VertDataAdd(nCo, q, ss);
+ VertDataAdd(nCo, r, ss);
+ VertDataMulN(nCo, 1.0f / numEdges, ss);
+ }
+
+ if (sharpCount > 1 || seam) {
+ VertDataZero(q, ss);
+
+ if (seam) {
+ avgSharpness = 1.0f;
+ sharpCount = seamEdges;
+ allSharp = 1;
+ }
+
+ for (i = 0; i < v->numEdges; i++) {
+ CCGEdge *e = v->edges[i];
+ float sharpness = EDGE_getSharpness(e, curLvl);
+
+ if (seam) {
+ if (_edge_isBoundary(e)) {
+ CCGVert *oV = _edge_getOtherVert(e, v);
+ VertDataAdd(q, VERT_getCo(oV, curLvl), ss);
+ }
+ }
+ else if (sharpness != 0.0f) {
+ CCGVert *oV = _edge_getOtherVert(e, v);
+ VertDataAdd(q, VERT_getCo(oV, curLvl), ss);
+ }
+ }
+
+ VertDataMulN(q, (float)1 / sharpCount, ss);
+
+ if (sharpCount != 2 || allSharp) {
+ /* q = q + (co - q) * avgSharpness */
+ VertDataCopy(r, co, ss);
+ VertDataSub(r, q, ss);
+ VertDataMulN(r, avgSharpness, ss);
+ VertDataAdd(q, r, ss);
+ }
+
+ /* r = co * 0.75 + q * 0.25 */
+ VertDataCopy(r, co, ss);
+ VertDataMulN(r, 0.75f, ss);
+ VertDataMulN(q, 0.25f, ss);
+ VertDataAdd(r, q, ss);
+
+ /* nCo = nCo + (r - nCo) * avgSharpness */
+ VertDataSub(r, nCo, ss);
+ VertDataMulN(r, avgSharpness, ss);
+ VertDataAdd(nCo, r, ss);
+ }
+
+ /* vert flags cleared later */
+ }
+
+ if (ss->useAgeCounts) {
+ for (i = 0; i < numEffectedV; i++) {
+ CCGVert *v = effectedV[i];
+ byte *userData = ccgSubSurf_getVertUserData(ss, v);
+ *((int *)&userData[ss->vertUserAgeOffset]) = ss->currentAge;
+ }
+
+ for (i = 0; i < numEffectedE; i++) {
+ CCGEdge *e = effectedE[i];
+ byte *userData = ccgSubSurf_getEdgeUserData(ss, e);
+ *((int *)&userData[ss->edgeUserAgeOffset]) = ss->currentAge;
+ }
+
+ for (i = 0; i < numEffectedF; i++) {
+ CCGFace *f = effectedF[i];
+ byte *userData = ccgSubSurf_getFaceUserData(ss, f);
+ *((int *)&userData[ss->faceUserAgeOffset]) = ss->currentAge;
+ }
+ }
+
+ for (i = 0; i < numEffectedE; i++) {
+ CCGEdge *e = effectedE[i];
+ VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl), ss);
+ VertDataCopy(EDGE_getCo(e, nextLvl, 2), VERT_getCo(e->v1, nextLvl), ss);
+ }
+ for (i = 0; i < numEffectedF; i++) {
+ CCGFace *f = effectedF[i];
+ for (S = 0; S < f->numVerts; S++) {
+ CCGEdge *e = FACE_getEdges(f)[S];
+ CCGEdge *prevE = FACE_getEdges(f)[(S + f->numVerts - 1) % f->numVerts];
+
+ VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), (float *)FACE_getCenterData(f), ss);
+ VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), (float *)FACE_getCenterData(f), ss);
+ VertDataCopy(
+ FACE_getIFCo(f, nextLvl, S, 1, 1), VERT_getCo(FACE_getVerts(f)[S], nextLvl), ss);
+ VertDataCopy(
+ FACE_getIECo(f, nextLvl, S, 1), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, 1), ss);
+
+ VertDataCopy(FACE_getIFCo(f, nextLvl, S, 1, 0),
+ _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize),
+ ss);
+ VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 1),
+ _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, 1, vertDataSize),
+ ss);
+ }
+ }
+
+ for (curLvl = 1; curLvl < subdivLevels; curLvl++)
+ ccgSubSurf__calcSubdivLevel(
+ ss, effectedV, effectedE, effectedF, numEffectedV, numEffectedE, numEffectedF, curLvl);
+
+ if (ss->calcVertNormals)
+ ccgSubSurf__calcVertNormals(
+ ss, effectedV, effectedE, effectedF, numEffectedV, numEffectedE, numEffectedF);
+
+ for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
+ CCGVert *v = effectedV[ptrIdx];
+ v->flags = 0;
+ }
+ for (ptrIdx = 0; ptrIdx < numEffectedE; ptrIdx++) {
+ CCGEdge *e = effectedE[ptrIdx];
+ e->flags = 0;
+ }
+
+ MEM_freeN(effectedF);
+ MEM_freeN(effectedE);
+ MEM_freeN(effectedV);
#ifdef DUMP_RESULT_GRIDS
- ccgSubSurf__dumpCoords(ss);
+ ccgSubSurf__dumpCoords(ss);
#endif
}
@@ -1280,31 +1298,31 @@ void ccgSubSurf__sync_legacy(CCGSubSurf *ss)
/* Update normals for specified faces. */
CCGError ccgSubSurf_updateNormals(CCGSubSurf *ss, CCGFace **effectedF, int numEffectedF)
{
- CCGVert **effectedV;
- CCGEdge **effectedE;
- int i, numEffectedV, numEffectedE, freeF;
-
- ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
- ccgSubSurf__effectedFaceNeighbours(ss, effectedF, numEffectedF,
- &effectedV, &numEffectedV, &effectedE, &numEffectedE);
-
- if (ss->calcVertNormals)
- ccgSubSurf__calcVertNormals(ss,
- effectedV, effectedE, effectedF,
- numEffectedV, numEffectedE, numEffectedF);
-
- for (i = 0; i < numEffectedV; i++)
- effectedV[i]->flags = 0;
- for (i = 0; i < numEffectedE; i++)
- effectedE[i]->flags = 0;
- for (i = 0; i < numEffectedF; i++)
- effectedF[i]->flags = 0;
-
- MEM_freeN(effectedE);
- MEM_freeN(effectedV);
- if (freeF) MEM_freeN(effectedF);
-
- return eCCGError_None;
+ CCGVert **effectedV;
+ CCGEdge **effectedE;
+ int i, numEffectedV, numEffectedE, freeF;
+
+ ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
+ ccgSubSurf__effectedFaceNeighbours(
+ ss, effectedF, numEffectedF, &effectedV, &numEffectedV, &effectedE, &numEffectedE);
+
+ if (ss->calcVertNormals)
+ ccgSubSurf__calcVertNormals(
+ ss, effectedV, effectedE, effectedF, numEffectedV, numEffectedE, numEffectedF);
+
+ for (i = 0; i < numEffectedV; i++)
+ effectedV[i]->flags = 0;
+ for (i = 0; i < numEffectedE; i++)
+ effectedE[i]->flags = 0;
+ for (i = 0; i < numEffectedF; i++)
+ effectedF[i]->flags = 0;
+
+ MEM_freeN(effectedE);
+ MEM_freeN(effectedV);
+ if (freeF)
+ MEM_freeN(effectedF);
+
+ return eCCGError_None;
}
/* compute subdivision levels from a given starting point, used by
@@ -1312,31 +1330,31 @@ CCGError ccgSubSurf_updateNormals(CCGSubSurf *ss, CCGFace **effectedF, int numEf
* certain level, and then subdividing that up to the highest level */
CCGError ccgSubSurf_updateLevels(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
{
- CCGVert **effectedV;
- CCGEdge **effectedE;
- int numEffectedV, numEffectedE, freeF, i;
- int curLvl, subdivLevels = ss->subdivLevels;
-
- ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
- ccgSubSurf__effectedFaceNeighbours(ss, effectedF, numEffectedF,
- &effectedV, &numEffectedV, &effectedE, &numEffectedE);
-
- for (curLvl = lvl; curLvl < subdivLevels; curLvl++) {
- ccgSubSurf__calcSubdivLevel(ss,
- effectedV, effectedE, effectedF,
- numEffectedV, numEffectedE, numEffectedF, curLvl);
- }
-
- for (i = 0; i < numEffectedV; i++)
- effectedV[i]->flags = 0;
- for (i = 0; i < numEffectedE; i++)
- effectedE[i]->flags = 0;
- for (i = 0; i < numEffectedF; i++)
- effectedF[i]->flags = 0;
-
- MEM_freeN(effectedE);
- MEM_freeN(effectedV);
- if (freeF) MEM_freeN(effectedF);
-
- return eCCGError_None;
+ CCGVert **effectedV;
+ CCGEdge **effectedE;
+ int numEffectedV, numEffectedE, freeF, i;
+ int curLvl, subdivLevels = ss->subdivLevels;
+
+ ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
+ ccgSubSurf__effectedFaceNeighbours(
+ ss, effectedF, numEffectedF, &effectedV, &numEffectedV, &effectedE, &numEffectedE);
+
+ for (curLvl = lvl; curLvl < subdivLevels; curLvl++) {
+ ccgSubSurf__calcSubdivLevel(
+ ss, effectedV, effectedE, effectedF, numEffectedV, numEffectedE, numEffectedF, curLvl);
+ }
+
+ for (i = 0; i < numEffectedV; i++)
+ effectedV[i]->flags = 0;
+ for (i = 0; i < numEffectedE; i++)
+ effectedE[i]->flags = 0;
+ for (i = 0; i < numEffectedF; i++)
+ effectedF[i]->flags = 0;
+
+ MEM_freeN(effectedE);
+ MEM_freeN(effectedV);
+ if (freeF)
+ MEM_freeN(effectedF);
+
+ return eCCGError_None;
}