7e8059e62fc0bfc615409ca64efb42939eb42e8e
[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 implementation.
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 #ifdef WITH_OPENSUBDIV
165         eSyncState_OpenSubdiv,
166 #endif
167 } SyncState;
168
169 struct CCGSubSurf {
170         EHash *vMap;   /* map of CCGVertHDL -> Vert */
171         EHash *eMap;   /* map of CCGEdgeHDL -> Edge */
172         EHash *fMap;  /* map of CCGFaceHDL -> Face */
173
174         CCGMeshIFC meshIFC;
175
176         CCGAllocatorIFC allocatorIFC;
177         CCGAllocatorHDL allocator;
178
179         int subdivLevels;
180         int numGrids;
181         int allowEdgeCreation;
182         float defaultCreaseValue;
183         void *defaultEdgeUserData;
184
185         void *q, *r;
186
187         /* Data for calc vert normals. */
188         int calcVertNormals;
189         int normalDataOffset;
190
191         /* Data for paint masks. */
192         int allocMask;
193         int maskDataOffset;
194
195         /* Data for age'ing (to debug sync). */
196         int currentAge;
197         int useAgeCounts;
198         int vertUserAgeOffset;
199         int edgeUserAgeOffset;
200         int faceUserAgeOffset;
201
202         /* Data used during syncing. */
203         SyncState syncState;
204
205         EHash *oldVMap, *oldEMap, *oldFMap;
206         int lenTempArrays;
207         CCGVert **tempVerts;
208         CCGEdge **tempEdges;
209
210 #ifdef WITH_OPENSUBDIV
211         /* Skip grids means no CCG geometry is created and subsurf is possible
212          * to be completely done on GPU.
213          */
214         bool skip_grids;
215
216         /* ** GPU backend. ** */
217
218         /* Compute device used by GL mesh. */
219         short osd_compute;
220         /* Coarse (base mesh) vertex coordinates.
221          *
222          * Filled in from the modifier stack and passed to OpenSubdiv compute
223          * on mesh display.
224          */
225         float (*osd_coarse_coords)[3];
226         int osd_num_coarse_coords;
227         /* Denotes whether coarse positions in the GL mesh are invalid.
228          * Used to avoid updating GL mesh coords on every redraw.
229          */
230         bool osd_coarse_coords_invalid;
231
232         /* GL mesh descriptor, used for refinment and draw. */
233         struct OpenSubdiv_GLMesh *osd_mesh;
234         /* Refiner which is used to create GL mesh.
235          *
236          * Refiner is created from the modifier stack and used later from the main
237          * thread to construct GL mesh to avoid threaded access to GL.
238          */
239         struct OpenSubdiv_TopologyRefinerDescr *osd_topology_refiner;  /* Only used at synchronization stage. */
240         /* Denotes whether osd_mesh is invalid now due to topology changes and needs
241          * to be reconstructed.
242          *
243          * Reconstruction happens from main thread due to OpenGL communication.
244          */
245         bool osd_mesh_invalid;
246         /* Vertex array used for osd_mesh draw. */
247         unsigned int osd_vao;
248
249         /* ** CPU backend. ** */
250
251         /* Limit evaluator, used to evaluate CCG. */
252         struct OpenSubdiv_EvaluatorDescr *osd_evaluator;
253         /* Next PTex face index, used while CCG synchronization
254          * to fill in PTex index of CCGFace.
255          */
256         int osd_next_face_ptex_index;
257 #endif
258 };
259
260 /* ** Utility macros ** */
261
262 #define CCGSUBSURF_alloc(ss, nb)            ((ss)->allocatorIFC.alloc((ss)->allocator, nb))
263 #define CCGSUBSURF_realloc(ss, ptr, nb, ob) ((ss)->allocatorIFC.realloc((ss)->allocator, ptr, nb, ob))
264 #define CCGSUBSURF_free(ss, ptr)            ((ss)->allocatorIFC.free((ss)->allocator, ptr))
265
266 #define VERT_getCo(v, lvl)                  ccg_vert_getCo(v, lvl, vertDataSize)
267 #define VERT_getNo(v, lvl)                  ccg_vert_getNo(v, lvl, vertDataSize, normalDataOffset)
268 #define EDGE_getCo(e, lvl, x)               ccg_edge_getCo(e, lvl, x, vertDataSize)
269 #define EDGE_getNo(e, lvl, x)               ccg_edge_getNo(e, lvl, x, vertDataSize, normalDataOffset)
270 #define FACE_getIFNo(f, lvl, S, x, y)       ccg_face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset)
271 //#define FACE_calcIFNo(f, lvl, S, x, y, no)  _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize)
272 #define FACE_getIENo(f, lvl, S, x)          ccg_face_getIENo(f, lvl, S, x, subdivLevels, vertDataSize, normalDataOffset)
273 #define FACE_getIECo(f, lvl, S, x)          ccg_face_getIECo(f, lvl, S, x, subdivLevels, vertDataSize)
274 #define FACE_getIFCo(f, lvl, S, x, y)       ccg_face_getIFCo(f, lvl, S, x, y, subdivLevels, vertDataSize)
275
276 #define NormZero(av)     { float *_a = (float *) av; _a[0] = _a[1] = _a[2] = 0.0f; } (void)0
277 #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
278 #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
279
280 /* ** General purpose functions  ** */
281
282 /* * CCGSubSurf.c * */
283
284 void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces);
285 void ccgSubSurf__effectedFaceNeighbours(CCGSubSurf *ss,
286                                         CCGFace **faces,
287                                         int numFaces,
288                                         CCGVert ***verts,
289                                         int *numVerts,
290                                         CCGEdge ***edges,
291                                         int *numEdges);
292
293 /* * CCGSubSurf_legacy.c * */
294
295 void ccgSubSurf__sync_legacy(CCGSubSurf *ss);
296
297 /* * CCGSubSurf_opensubdiv.c * */
298
299 void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss);
300
301 /* Delayed free routines. Will do actual free if called from
302  * main thread and schedule free for later free otherwise.
303  */
304
305 #ifdef WITH_OPENSUBDIV
306 void ccgSubSurf__delete_osdGLMesh(struct OpenSubdiv_GLMesh *osd_mesh);
307 void ccgSubSurf__delete_vertex_array(unsigned int vao);
308 void ccgSubSurf__delete_pending(void);
309 #endif
310
311 /* * CCGSubSurf_opensubdiv_converter.c * */
312
313 struct OpenSubdiv_Converter;
314
315 void ccgSubSurf_converter_setup_from_derivedmesh(
316         CCGSubSurf *ss,
317         struct DerivedMesh *dm,
318         struct OpenSubdiv_Converter *converter);
319
320 void ccgSubSurf_converter_setup_from_ccg(
321         CCGSubSurf *ss,
322         struct OpenSubdiv_Converter *converter);
323
324 void ccgSubSurf_converter_free(
325         struct OpenSubdiv_Converter *converter);
326
327 /* * CCGSubSurf_util.c * */
328
329 #ifdef DUMP_RESULT_GRIDS
330 void ccgSubSurf__dumpCoords(CCGSubSurf *ss);
331 #endif
332
333 #include "CCGSubSurf_inline.h"
334
335 #endif  /* __CCGSUBSURF_INTERN_H__ */