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_intern.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_intern.h')
-rw-r--r-- | source/blender/blenkernel/intern/CCGSubSurf_intern.h | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h new file mode 100644 index 00000000000..1689ac482ef --- /dev/null +++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h @@ -0,0 +1,277 @@ +/* + * ***** 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_intern.h + * \ingroup bke + */ + +#ifndef __CCGSUBSURF_INTERN_H__ +#define __CCGSUBSURF_INTERN_H__ + +/** + * Definitions which defines internal behavior of CCGSubSurf. + */ + +/* Define this to see dump of the grids after the subsurf applied. */ +#undef DUMP_RESULT_GRIDS + +/* used for normalize_v3 in BLI_math_vector + * float.h's FLT_EPSILON causes trouble with subsurf normals - campbell */ +#define EPSILON (1.0e-35f) + +/* With this limit a single triangle becomes over 3 million faces */ +#define CCGSUBSURF_LEVEL_MAX 11 + +/** + * Common type definitions. + */ + +typedef unsigned char byte; + +/** + * Hash implementation. + */ + +typedef struct _EHEntry { + struct _EHEntry *next; + void *key; +} EHEntry; + +typedef struct _EHash { + EHEntry **buckets; + int numEntries, curSize, curSizeIdx; + + CCGAllocatorIFC allocatorIFC; + CCGAllocatorHDL allocator; +} EHash; + +typedef void (*EHEntryFreeFP)(EHEntry *, void *); + +#define EHASH_alloc(eh, nb) ((eh)->allocatorIFC.alloc((eh)->allocator, nb)) +#define EHASH_free(eh, ptr) ((eh)->allocatorIFC.free((eh)->allocator, ptr)) +#define EHASH_hash(eh, item) (((uintptr_t) (item)) % ((unsigned int) (eh)->curSize)) + +/* Generic hash functions. */ + +EHash *ccg_ehash_new(int estimatedNumEntries, + CCGAllocatorIFC *allocatorIFC, + CCGAllocatorHDL allocator); +void ccg_ehash_free(EHash *eh, EHEntryFreeFP freeEntry, void *userData); +void ccg_ehash_insert(EHash *eh, EHEntry *entry); +void *ccg_ehash_lookupWithPrev(EHash *eh, void *key, void ***prevp_r); +void *ccg_ehash_lookup(EHash *eh, void *key); + +/* Hash elements iteration. */ + +void ccg_ehashIterator_init(EHash *eh, EHashIterator *ehi); +void *ccg_ehashIterator_getCurrent(EHashIterator *ehi); +void ccg_ehashIterator_next(EHashIterator *ehi); +int ccg_ehashIterator_isStopped(EHashIterator *ehi); + +/** + * Standard allocator implementarion. + */ + +CCGAllocatorIFC *ccg_getStandardAllocatorIFC(void); + +/** + * Catmull-Clark Gridding Subdivision Surface. + */ + +/* TODO(sergey): Get rid of this, it's more or less a bad level call. */ +struct DerivedMesh; + +/* ** Data structures, constants. enums ** */ + +enum { + Vert_eEffected = (1 << 0), + Vert_eChanged = (1 << 1), + Vert_eSeam = (1 << 2) +} /*VertFlags*/; + +enum { + Edge_eEffected = (1 << 0) +} /*CCGEdgeFlags*/; + +enum { + Face_eEffected = (1 << 0) +} /*FaceFlags*/; + +struct CCGVert { + CCGVert *next; /* EHData.next */ + CCGVertHDL vHDL; /* EHData.key */ + + short numEdges, numFaces, flags; + int osd_index; /* Index of the vertex in the map, used by OSD. */ + + CCGEdge **edges; + CCGFace **faces; + /* byte *levelData; */ + /* byte *userData; */ +}; + +struct CCGEdge { + CCGEdge *next; /* EHData.next */ + CCGEdgeHDL eHDL; /* EHData.key */ + + short numFaces, flags; + float crease; + + CCGVert *v0, *v1; + CCGFace **faces; + + /* byte *levelData; */ + /* byte *userData; */ +}; + +struct CCGFace { + CCGFace *next; /* EHData.next */ + CCGFaceHDL fHDL; /* EHData.key */ + + short numVerts, flags; + int osd_index; + + /* CCGVert **verts; */ + /* CCGEdge **edges; */ + /* byte *centerData; */ + /* byte **gridData; */ + /* byte *userData; */ +}; + +typedef enum { + eSyncState_None = 0, + eSyncState_Vert, + eSyncState_Edge, + eSyncState_Face, + eSyncState_Partial, +} SyncState; + +struct CCGSubSurf { + EHash *vMap; /* map of CCGVertHDL -> Vert */ + EHash *eMap; /* map of CCGEdgeHDL -> Edge */ + EHash *fMap; /* map of CCGFaceHDL -> Face */ + + CCGMeshIFC meshIFC; + + CCGAllocatorIFC allocatorIFC; + CCGAllocatorHDL allocator; + + int subdivLevels; + int numGrids; + int allowEdgeCreation; + float defaultCreaseValue; + void *defaultEdgeUserData; + + void *q, *r; + + /* Data for calc vert normals. */ + int calcVertNormals; + int normalDataOffset; + + /* Data for paint masks. */ + int allocMask; + int maskDataOffset; + + /* Data for age'ing (to debug sync). */ + int currentAge; + int useAgeCounts; + int vertUserAgeOffset; + int edgeUserAgeOffset; + int faceUserAgeOffset; + + /* Data used during syncing. */ + SyncState syncState; + + EHash *oldVMap, *oldEMap, *oldFMap; + int lenTempArrays; + CCGVert **tempVerts; + CCGEdge **tempEdges; +}; + +/* ** Utility macros ** */ + +#define CCGSUBSURF_alloc(ss, nb) ((ss)->allocatorIFC.alloc((ss)->allocator, nb)) +#define CCGSUBSURF_realloc(ss, ptr, nb, ob) ((ss)->allocatorIFC.realloc((ss)->allocator, ptr, nb, ob)) +#define CCGSUBSURF_free(ss, ptr) ((ss)->allocatorIFC.free((ss)->allocator, ptr)) + +#define VERT_getCo(v, lvl) ccg_vert_getCo(v, lvl, vertDataSize) +#define VERT_getNo(v, lvl) ccg_vert_getNo(v, lvl, vertDataSize, normalDataOffset) +#define EDGE_getCo(e, lvl, x) ccg_edge_getCo(e, lvl, x, vertDataSize) +#define EDGE_getNo(e, lvl, x) ccg_edge_getNo(e, lvl, x, vertDataSize, normalDataOffset) +#define FACE_getIFNo(f, lvl, S, x, y) ccg_face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset) +//#define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize) +#define FACE_getIENo(f, lvl, S, x) ccg_face_getIENo(f, lvl, S, x, subdivLevels, vertDataSize, normalDataOffset) +#define FACE_getIECo(f, lvl, S, x) ccg_face_getIECo(f, lvl, S, x, subdivLevels, vertDataSize) +#define FACE_getIFCo(f, lvl, S, x, y) ccg_face_getIFCo(f, lvl, S, x, y, subdivLevels, vertDataSize) + +#define NormZero(av) { float *_a = (float *) av; _a[0] = _a[1] = _a[2] = 0.0f; } (void)0 +#define NormCopy(av, bv) { float *_a = (float *) av, *_b = (float *) bv; _a[0] = _b[0]; _a[1] = _b[1]; _a[2] = _b[2]; } (void)0 +#define NormAdd(av, bv) { float *_a = (float *) av, *_b = (float *) bv; _a[0] += _b[0]; _a[1] += _b[1]; _a[2] += _b[2]; } (void)0 + +/* ** General purpose functions ** */ + +/* * CCGSubSurf.c * */ + +void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces); +void ccgSubSurf__effectedFaceNeighbours(CCGSubSurf *ss, + CCGFace **faces, + int numFaces, + CCGVert ***verts, + int *numVerts, + CCGEdge ***edges, + int *numEdges); + +/* * CCGSubSurf_legacy.c * */ + +void ccgSubSurf__sync_legacy(CCGSubSurf *ss); + +/* * CCGSubSurf_opensubdiv.c * */ + +void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss); + +int ccgSubSurf__getNumOsdBaseVerts(const CCGSubSurf *ss); +int ccgSubSurf__getNumOsdBaseEdges(const CCGSubSurf *ss); +int ccgSubSurf__getNumOsdBaseFaces(const CCGSubSurf *ss); + +/* * CCGSubSurf_opensubdiv_converter.c * */ + +struct OpenSubdiv_Converter; + +void ccgSubSurf_converter_setup_from_derivedmesh( + CCGSubSurf *ss, + struct DerivedMesh *dm, + struct OpenSubdiv_Converter *converter); + +void ccgSubSurf_converter_setup_from_ccg( + CCGSubSurf *ss, + struct OpenSubdiv_Converter *converter); + +void ccgSubSurf_converter_free( + struct OpenSubdiv_Converter *converter); + +/* * CCGSubSurf_util.c * */ + +#ifdef DUMP_RESULT_GRIDS +void ccgSubSurf__dumpCoords(CCGSubSurf *ss); +#endif + +#include "CCGSubSurf_inline.h" + +#endif /* __CCGSUBSURF_INTERN_H__ */ |