diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-07-20 16:05:16 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-07-20 23:29:25 +0300 |
commit | ccc3c2dbda36f00e74064e993d7e98bf8ab32a58 (patch) | |
tree | 43ac1a879558089e1cb7d6b7b7252fb91f711e76 /source/blender/blenkernel/intern/CCGSubSurf_inline.h | |
parent | 6190d75b5a8854f04c05cbd14a27837763fa5b95 (diff) |
CCGSubSurf: Split file into several smaller ones
This is a preparation commit for having OpenSubdiv integrated into Blender
and new layout is the following:
- CCGSubSurf.c contains implementation of common functions used by both
legacy subdivisions code and by the new code in the future.
- CCGSubSurf_inline.h contains internal functions which are to be inlined
due to the performance reasons. Those functions are only ment to be used
bu CCGSubSurf* files.
- CCGSubSurf_intern.h contains declarations of private functions and data
structures used by CCGSubSurf module.
- CCGSubSurf_legacy.c contains legacy implementation of subdivision algorithm.
- CCHSubSurf_util.c contains utility functions which are not directly related
on the subdivision code (i.e. debug functions, hash implementation etc).
There should be no functional changes so far.
Diffstat (limited to 'source/blender/blenkernel/intern/CCGSubSurf_inline.h')
-rw-r--r-- | source/blender/blenkernel/intern/CCGSubSurf_inline.h | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_inline.h b/source/blender/blenkernel/intern/CCGSubSurf_inline.h new file mode 100644 index 00000000000..183578c26ce --- /dev/null +++ b/source/blender/blenkernel/intern/CCGSubSurf_inline.h @@ -0,0 +1,269 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/CCGSubSurf_inline.h + * \ingroup bke + */ + +#ifndef __CCGSUBSURF_INLINE_H__ +#define __CCGSUBSURF_INLINE_H__ + +BLI_INLINE int ccg_gridsize(int level) +{ + BLI_assert(level > 0); + BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1); + return (1 << (level - 1)) + 1; +} + +BLI_INLINE int ccg_edgesize(int level) +{ + BLI_assert(level > 0); + BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1); + return 1 + (1 << level); +} + +BLI_INLINE int ccg_spacing(int high_level, int low_level) +{ + BLI_assert(high_level > 0 && low_level > 0); + BLI_assert(high_level >= low_level); + BLI_assert((high_level - low_level) <= CCGSUBSURF_LEVEL_MAX); + return 1 << (high_level - low_level); +} + +BLI_INLINE int ccg_edgebase(int level) +{ + BLI_assert(level > 0); + BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1); + return level + (1 << level) - 1; +} + +/* **** */ + +BLI_INLINE byte *VERT_getLevelData(CCGVert *v) +{ + return (byte *)(&(v)[1]); +} + +BLI_INLINE byte *EDGE_getLevelData(CCGEdge *e) +{ + return (byte *)(&(e)[1]); +} + +BLI_INLINE CCGVert **FACE_getVerts(CCGFace *f) +{ + return (CCGVert **)(&f[1]); +} + +BLI_INLINE CCGEdge **FACE_getEdges(CCGFace *f) +{ + return (CCGEdge **)(&(FACE_getVerts(f)[f->numVerts])); +} + +BLI_INLINE byte *FACE_getCenterData(CCGFace *f) +{ + return (byte *)(&(FACE_getEdges(f)[(f)->numVerts])); +} + +/* **** */ + +BLI_INLINE void *ccg_vert_getCo(CCGVert *v, int lvl, int dataSize) +{ + return &VERT_getLevelData(v)[lvl * dataSize]; +} + +BLI_INLINE float *ccg_vert_getNo(CCGVert *v, + int lvl, + int dataSize, + int normalDataOffset) +{ + return (float *) &VERT_getLevelData(v)[lvl * dataSize + normalDataOffset]; +} + +BLI_INLINE void *ccg_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize) +{ + int levelBase = ccg_edgebase(lvl); + return &EDGE_getLevelData(e)[dataSize * (levelBase + x)]; +} + +BLI_INLINE float *ccg_edge_getNo(CCGEdge *e, + int lvl, + int x, + int dataSize, + int normalDataOffset) +{ + int levelBase = ccg_edgebase(lvl); + return (float *) &EDGE_getLevelData(e)[dataSize * (levelBase + x) + normalDataOffset]; +} + +BLI_INLINE void *ccg_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize) +{ + int maxGridSize = ccg_gridsize(levels); + int spacing = ccg_spacing(levels, lvl); + byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize)); + return &gridBase[dataSize * x * spacing]; +} + +BLI_INLINE void *ccg_face_getIENo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize, int normalDataOffset) +{ + int maxGridSize = ccg_gridsize(levels); + int spacing = ccg_spacing(levels, lvl); + byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize)); + return &gridBase[dataSize * x * spacing + normalDataOffset]; +} + +BLI_INLINE void *ccg_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize) +{ + int maxGridSize = ccg_gridsize(levels); + int spacing = ccg_spacing(levels, lvl); + byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize)); + return &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing)]; +} + +BLI_INLINE float *ccg_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) +{ + int maxGridSize = ccg_gridsize(levels); + int spacing = ccg_spacing(levels, lvl); + byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize)); + return (float *) &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing) + normalDataOffset]; +} + + +BLI_INLINE int ccg_face_getVertIndex(CCGFace *f, CCGVert *v) +{ + int i; + for (i = 0; i < f->numVerts; i++) + if (FACE_getVerts(f)[i] == v) + return i; + return -1; +} + +BLI_INLINE int ccg_face_getEdgeIndex(CCGFace *f, CCGEdge *e) +{ + int i; + for (i = 0; i < f->numVerts; i++) + if (FACE_getEdges(f)[i] == e) + return i; + return -1; +} + +BLI_INLINE void *ccg_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int f_ed_idx, int lvl, int eX, int eY, int levels, int dataSize) +{ + int maxGridSize = ccg_gridsize(levels); + int spacing = ccg_spacing(levels, lvl); + int x, y, cx, cy; + + BLI_assert(f_ed_idx == ccg_face_getEdgeIndex(f, e)); + + eX = eX * spacing; + eY = eY * spacing; + if (e->v0 != FACE_getVerts(f)[f_ed_idx]) { + eX = (maxGridSize * 2 - 1) - 1 - eX; + } + y = maxGridSize - 1 - eX; + x = maxGridSize - 1 - eY; + if (x < 0) { + f_ed_idx = (f_ed_idx + f->numVerts - 1) % f->numVerts; + cx = y; + cy = -x; + } + else if (y < 0) { + f_ed_idx = (f_ed_idx + 1) % f->numVerts; + cx = -y; + cy = x; + } + else { + cx = x; + cy = y; + } + return ccg_face_getIFCo(f, levels, f_ed_idx, cx, cy, levels, dataSize); +} + +BLI_INLINE void Normalize(float no[3]) +{ + const float length = sqrtf(no[0] * no[0] + no[1] * no[1] + no[2] * no[2]); + + if (length > EPSILON) { + const float length_inv = 1.0f / length; + + no[0] *= length_inv; + no[1] *= length_inv; + no[2] *= length_inv; + } + else { + NormZero(no); + } +} + +/* Data layers mathematics. */ + +BLI_INLINE int VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss) +{ + int i; + for (i = 0; i < ss->meshIFC.numLayers; i++) { + if (a[i] != b[i]) + return 0; + } + return 1; +} + +BLI_INLINE void VertDataZero(float v[], const CCGSubSurf *ss) +{ + memset(v, 0, sizeof(float) * ss->meshIFC.numLayers); +} + +BLI_INLINE void VertDataCopy(float dst[], const float src[], const CCGSubSurf *ss) +{ + int i; + for (i = 0; i < ss->meshIFC.numLayers; i++) + dst[i] = src[i]; +} + +BLI_INLINE void VertDataAdd(float a[], const float b[], const CCGSubSurf *ss) +{ + int i; + for (i = 0; i < ss->meshIFC.numLayers; i++) + a[i] += b[i]; +} + +BLI_INLINE void VertDataSub(float a[], const float b[], const CCGSubSurf *ss) +{ + int i; + for (i = 0; i < ss->meshIFC.numLayers; i++) + a[i] -= b[i]; +} + +BLI_INLINE void VertDataMulN(float v[], float f, const CCGSubSurf *ss) +{ + int i; + for (i = 0; i < ss->meshIFC.numLayers; i++) + v[i] *= f; +} + +BLI_INLINE void VertDataAvg4(float v[], + const float a[], const float b[], + const float c[], const float d[], + const CCGSubSurf *ss) +{ + int i; + for (i = 0; i < ss->meshIFC.numLayers; i++) + v[i] = (a[i] + b[i] + c[i] + d[i]) * 0.25f; +} + +#endif /* __CCGSUBSURF_INLINE_H__ */ |