CCGSubSurf: Split file into several smaller ones
[blender.git] / source / blender / blenkernel / intern / CCGSubSurf_intern.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/blenkernel/intern/CCGSubSurf_intern.h
22  *  \ingroup bke
23  */
24
25 #ifndef __CCGSUBSURF_INTERN_H__
26 #define __CCGSUBSURF_INTERN_H__
27
28 /**
29  * Definitions which defines internal behavior of CCGSubSurf.
30  */
31
32 /* Define this to see dump of the grids after the subsurf applied. */
33 #undef DUMP_RESULT_GRIDS
34
35 /* used for normalize_v3 in BLI_math_vector
36  * float.h's FLT_EPSILON causes trouble with subsurf normals - campbell */
37 #define EPSILON (1.0e-35f)
38
39 /* With this limit a single triangle becomes over 3 million faces */
40 #define CCGSUBSURF_LEVEL_MAX 11
41
42 /**
43  * Common type definitions.
44  */
45
46 typedef unsigned char byte;
47
48 /**
49  * Hash implementation.
50  */
51
52 typedef struct _EHEntry {
53         struct _EHEntry *next;
54         void *key;
55 } EHEntry;
56
57 typedef struct _EHash {
58         EHEntry **buckets;
59         int numEntries, curSize, curSizeIdx;
60
61         CCGAllocatorIFC allocatorIFC;
62         CCGAllocatorHDL allocator;
63 } EHash;
64
65 typedef void (*EHEntryFreeFP)(EHEntry *, void *);
66
67 #define EHASH_alloc(eh, nb)     ((eh)->allocatorIFC.alloc((eh)->allocator, nb))
68 #define EHASH_free(eh, ptr)     ((eh)->allocatorIFC.free((eh)->allocator, ptr))
69 #define EHASH_hash(eh, item)    (((uintptr_t) (item)) % ((unsigned int) (eh)->curSize))
70
71 /* Generic hash functions. */
72
73 EHash *ccg_ehash_new(int estimatedNumEntries,
74                      CCGAllocatorIFC *allocatorIFC,
75                      CCGAllocatorHDL allocator);
76 void ccg_ehash_free(EHash *eh, EHEntryFreeFP freeEntry, void *userData);
77 void ccg_ehash_insert(EHash *eh, EHEntry *entry);
78 void *ccg_ehash_lookupWithPrev(EHash *eh, void *key, void ***prevp_r);
79 void *ccg_ehash_lookup(EHash *eh, void *key);
80
81 /* Hash elements iteration. */
82
83 void ccg_ehashIterator_init(EHash *eh, EHashIterator *ehi);
84 void *ccg_ehashIterator_getCurrent(EHashIterator *ehi);
85 void ccg_ehashIterator_next(EHashIterator *ehi);
86 int ccg_ehashIterator_isStopped(EHashIterator *ehi);
87
88 /**
89  * Standard allocator implementarion.
90  */
91
92 CCGAllocatorIFC *ccg_getStandardAllocatorIFC(void);
93
94 /**
95  * Catmull-Clark Gridding Subdivision Surface.
96  */
97
98 /* TODO(sergey): Get rid of this, it's more or less a bad level call. */
99 struct DerivedMesh;
100
101 /* ** Data structures, constants. enums ** */
102
103 enum {
104         Vert_eEffected =    (1 << 0),
105         Vert_eChanged =     (1 << 1),
106         Vert_eSeam =        (1 << 2)
107 } /*VertFlags*/;
108
109 enum {
110         Edge_eEffected =    (1 << 0)
111 } /*CCGEdgeFlags*/;
112
113 enum {
114         Face_eEffected =    (1 << 0)
115 } /*FaceFlags*/;
116
117 struct CCGVert {
118         CCGVert *next;    /* EHData.next */
119         CCGVertHDL vHDL;  /* EHData.key */
120
121         short numEdges, numFaces, flags;
122         int osd_index;  /* Index of the vertex in the map, used by OSD. */
123
124         CCGEdge **edges;
125         CCGFace **faces;
126         /* byte *levelData; */
127         /* byte *userData; */
128 };
129
130 struct CCGEdge {
131         CCGEdge *next;   /* EHData.next */
132         CCGEdgeHDL eHDL; /* EHData.key */
133
134         short numFaces, flags;
135         float crease;
136
137         CCGVert *v0, *v1;
138         CCGFace **faces;
139
140         /* byte *levelData; */
141         /* byte *userData; */
142 };
143
144 struct CCGFace {
145         CCGFace     *next;  /* EHData.next */
146         CCGFaceHDL fHDL;    /* EHData.key */
147
148         short numVerts, flags;
149         int osd_index;
150
151         /* CCGVert **verts; */
152         /* CCGEdge **edges; */
153         /* byte *centerData; */
154         /* byte **gridData; */
155         /* byte *userData; */
156 };
157
158 typedef enum {
159         eSyncState_None = 0,
160         eSyncState_Vert,
161         eSyncState_Edge,
162         eSyncState_Face,
163         eSyncState_Partial,
164 } SyncState;
165
166 struct CCGSubSurf {
167         EHash *vMap;   /* map of CCGVertHDL -> Vert */
168         EHash *eMap;   /* map of CCGEdgeHDL -> Edge */
169         EHash *fMap;  /* map of CCGFaceHDL -> Face */
170
171         CCGMeshIFC meshIFC;
172
173         CCGAllocatorIFC allocatorIFC;
174         CCGAllocatorHDL allocator;
175
176         int subdivLevels;
177         int numGrids;
178         int allowEdgeCreation;
179         float defaultCreaseValue;
180         void *defaultEdgeUserData;
181
182         void *q, *r;
183
184         /* Data for calc vert normals. */
185         int calcVertNormals;
186         int normalDataOffset;
187
188         /* Data for paint masks. */
189         int allocMask;
190         int maskDataOffset;
191
192         /* Data for age'ing (to debug sync). */
193         int currentAge;
194         int useAgeCounts;
195         int vertUserAgeOffset;
196         int edgeUserAgeOffset;
197         int faceUserAgeOffset;
198
199         /* Data used during syncing. */
200         SyncState syncState;
201
202         EHash *oldVMap, *oldEMap, *oldFMap;
203         int lenTempArrays;
204         CCGVert **tempVerts;
205         CCGEdge **tempEdges;
206 };
207
208 /* ** Utility macros ** */
209
210 #define CCGSUBSURF_alloc(ss, nb)            ((ss)->allocatorIFC.alloc((ss)->allocator, nb))
211 #define CCGSUBSURF_realloc(ss, ptr, nb, ob) ((ss)->allocatorIFC.realloc((ss)->allocator, ptr, nb, ob))
212 #define CCGSUBSURF_free(ss, ptr)            ((ss)->allocatorIFC.free((ss)->allocator, ptr))
213
214 #define VERT_getCo(v, lvl)                  ccg_vert_getCo(v, lvl, vertDataSize)
215 #define VERT_getNo(v, lvl)                  ccg_vert_getNo(v, lvl, vertDataSize, normalDataOffset)
216 #define EDGE_getCo(e, lvl, x)               ccg_edge_getCo(e, lvl, x, vertDataSize)
217 #define EDGE_getNo(e, lvl, x)               ccg_edge_getNo(e, lvl, x, vertDataSize, normalDataOffset)
218 #define FACE_getIFNo(f, lvl, S, x, y)       ccg_face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset)
219 //#define FACE_calcIFNo(f, lvl, S, x, y, no)  _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize)
220 #define FACE_getIENo(f, lvl, S, x)          ccg_face_getIENo(f, lvl, S, x, subdivLevels, vertDataSize, normalDataOffset)
221 #define FACE_getIECo(f, lvl, S, x)          ccg_face_getIECo(f, lvl, S, x, subdivLevels, vertDataSize)
222 #define FACE_getIFCo(f, lvl, S, x, y)       ccg_face_getIFCo(f, lvl, S, x, y, subdivLevels, vertDataSize)
223
224 #define NormZero(av)     { float *_a = (float *) av; _a[0] = _a[1] = _a[2] = 0.0f; } (void)0
225 #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
226 #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
227
228 /* ** General purpose functions  ** */
229
230 /* * CCGSubSurf.c * */
231
232 void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces);
233 void ccgSubSurf__effectedFaceNeighbours(CCGSubSurf *ss,
234                                         CCGFace **faces,
235                                         int numFaces,
236                                         CCGVert ***verts,
237                                         int *numVerts,
238                                         CCGEdge ***edges,
239                                         int *numEdges);
240
241 /* * CCGSubSurf_legacy.c * */
242
243 void ccgSubSurf__sync_legacy(CCGSubSurf *ss);
244
245 /* * CCGSubSurf_opensubdiv.c * */
246
247 void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss);
248
249 int ccgSubSurf__getNumOsdBaseVerts(const CCGSubSurf *ss);
250 int ccgSubSurf__getNumOsdBaseEdges(const CCGSubSurf *ss);
251 int ccgSubSurf__getNumOsdBaseFaces(const CCGSubSurf *ss);
252
253 /* * CCGSubSurf_opensubdiv_converter.c * */
254
255 struct OpenSubdiv_Converter;
256
257 void ccgSubSurf_converter_setup_from_derivedmesh(
258         CCGSubSurf *ss,
259         struct DerivedMesh *dm,
260         struct OpenSubdiv_Converter *converter);
261
262 void ccgSubSurf_converter_setup_from_ccg(
263         CCGSubSurf *ss,
264         struct OpenSubdiv_Converter *converter);
265
266 void ccgSubSurf_converter_free(
267         struct OpenSubdiv_Converter *converter);
268
269 /* * CCGSubSurf_util.c * */
270
271 #ifdef DUMP_RESULT_GRIDS
272 void ccgSubSurf__dumpCoords(CCGSubSurf *ss);
273 #endif
274
275 #include "CCGSubSurf_inline.h"
276
277 #endif  /* __CCGSUBSURF_INTERN_H__ */