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