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