Welcome to mirror list, hosted at ThFree Co, Russian Federation.

CCGSubSurf_intern.h « intern « blenkernel « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f9e0fbb46dbc5c08ed9daf3882709cca85d00142 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
/* SPDX-License-Identifier: GPL-2.0-or-later */

/** \file
 * \ingroup bke
 */

#pragma once

/**
 * 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 implementation.
 */

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)
#if 0
#  define FACE_calcIFNo(f, lvl, S, x, y, no) \
    _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize)
#endif
#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__effectedFaceNeighbors(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);

/* * 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"