Blender V4.5
CCGSubSurf_util.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
14#include "BLI_utildefines.h" /* for BLI_assert */
15
16#include "CCGSubSurf.h"
17#include "CCGSubSurf_intern.h"
18
22
23static int kHashSizes[] = {
24 1, 3, 5, 11, 17, 37, 67, 131, 257, 521,
25 1031, 2053, 4099, 8209, 16411, 32771, 65537, 131101, 262147, 524309,
26 1048583, 2097169, 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459,
27};
28
29/* -------------------------------------------------------------------- */
32
33EHash *ccg_ehash_new(int estimatedNumEntries,
34 CCGAllocatorIFC *allocatorIFC,
35 CCGAllocatorHDL allocator)
36{
37 EHash *eh = static_cast<EHash *>(allocatorIFC->alloc(allocator, sizeof(*eh)));
38 eh->allocatorIFC = *allocatorIFC;
39 eh->allocator = allocator;
40 eh->numEntries = 0;
41 eh->curSizeIdx = 0;
42 while (kHashSizes[eh->curSizeIdx] < estimatedNumEntries) {
43 eh->curSizeIdx++;
44 }
45 eh->curSize = kHashSizes[eh->curSizeIdx];
46 eh->buckets = EHASH_alloc(eh, eh->curSize * sizeof(*eh->buckets));
47 memset(eh->buckets, 0, eh->curSize * sizeof(*eh->buckets));
48
49 return eh;
50}
51
52void ccg_ehash_free(EHash *eh, EHEntryFreeFP freeEntry, void *user_data)
53{
54 int numBuckets = eh->curSize;
55
56 while (numBuckets--) {
57 EHEntry *entry = eh->buckets[numBuckets];
58
59 while (entry) {
60 EHEntry *next = entry->next;
61
62 freeEntry(entry, user_data);
63
64 entry = next;
65 }
66 }
67
68 EHASH_free(eh, eh->buckets);
69 EHASH_free(eh, eh);
70}
71
73{
74 int numBuckets = eh->curSize;
75 int hash = EHASH_hash(eh, entry->key);
76 entry->next = eh->buckets[hash];
77 eh->buckets[hash] = entry;
78 eh->numEntries++;
79
80 if (UNLIKELY(eh->numEntries > (numBuckets * 3))) {
81 EHEntry **oldBuckets = eh->buckets;
82 eh->curSize = kHashSizes[++eh->curSizeIdx];
83
84 eh->buckets = EHASH_alloc(eh, eh->curSize * sizeof(*eh->buckets));
85 memset(eh->buckets, 0, eh->curSize * sizeof(*eh->buckets));
86
87 while (numBuckets--) {
88 for (entry = oldBuckets[numBuckets]; entry;) {
89 EHEntry *next = entry->next;
90
91 hash = EHASH_hash(eh, entry->key);
92 entry->next = eh->buckets[hash];
93 eh->buckets[hash] = entry;
94
95 entry = next;
96 }
97 }
98
99 EHASH_free(eh, oldBuckets);
100 }
101}
102
103void *ccg_ehash_lookupWithPrev(EHash *eh, void *key, void ***prevp_r)
104{
105 int hash = EHASH_hash(eh, key);
106 void **prevp = (void **)&eh->buckets[hash];
107 EHEntry *entry;
108
109 for (; (entry = static_cast<EHEntry *>(*prevp)); prevp = (void **)&entry->next) {
110 if (entry->key == key) {
111 *prevp_r = prevp;
112 return entry;
113 }
114 }
115
116 return nullptr;
117}
118
119void *ccg_ehash_lookup(EHash *eh, void *key)
120{
121 int hash = EHASH_hash(eh, key);
122 EHEntry *entry;
123
124 for (entry = eh->buckets[hash]; entry; entry = entry->next) {
125 if (entry->key == key) {
126 break;
127 }
128 }
129
130 return entry;
131}
132
134
135/* -------------------------------------------------------------------- */
138
140{
141 /* fill all members */
142 ehi->eh = eh;
143 ehi->curBucket = -1;
144 ehi->curEntry = nullptr;
145
146 while (!ehi->curEntry) {
147 ehi->curBucket++;
148 if (ehi->curBucket == ehi->eh->curSize) {
149 break;
150 }
151 ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
152 }
153}
154
156{
157 return ehi->curEntry;
158}
159
161{
162 if (ehi->curEntry) {
163 ehi->curEntry = ehi->curEntry->next;
164 while (!ehi->curEntry) {
165 ehi->curBucket++;
166 if (ehi->curBucket == ehi->eh->curSize) {
167 break;
168 }
169 ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
170 }
171 }
172}
174{
175 return !ehi->curEntry;
176}
177
179
180/* -------------------------------------------------------------------- */
183
184static void *_stdAllocator_alloc(CCGAllocatorHDL /*a*/, int numBytes)
185{
186 return MEM_mallocN(numBytes, "CCG standard alloc");
187}
188
189static void *_stdAllocator_realloc(CCGAllocatorHDL /*a*/, void *ptr, int newSize, int /*oldSize*/)
190{
191 return MEM_reallocN(ptr, newSize);
192}
193
194static void _stdAllocator_free(CCGAllocatorHDL /*a*/, void *ptr)
195{
196 MEM_freeN(ptr);
197}
198
200{
201 static CCGAllocatorIFC ifc;
202
206 ifc.release = nullptr;
207
208 return &ifc;
209}
210
212
213/* -------------------------------------------------------------------- */
216
217#ifdef DUMP_RESULT_GRIDS
218void ccgSubSurf__dumpCoords(CCGSubSurf *ss)
219{
220 int vertDataSize = ss->meshIFC.vertDataSize;
221 int subdivLevels = ss->subdivLevels;
222 int gridSize = ccg_gridsize(subdivLevels);
223 int edgeSize = ccg_edgesize(subdivLevels);
224 int i, index, S;
225
226 for (i = 0, index = 0; i < ss->vMap->curSize; i++) {
227 CCGVert *v = (CCGVert *)ss->vMap->buckets[i];
228 for (; v; v = v->next, index++) {
229 float *co = VERT_getCo(v, subdivLevels);
230 printf("vertex index=%d, co=(%f, %f, %f)\n", index, co[0], co[1], co[2]);
231 }
232 }
233
234 for (i = 0, index = 0; i < ss->eMap->curSize; i++) {
235 CCGEdge *e = (CCGEdge *)ss->eMap->buckets[i];
236 for (; e; e = e->next, index++) {
237 int x;
238 float *co = VERT_getCo(e->v0, subdivLevels);
239 printf("edge index=%d, start_co=(%f, %f, %f)\n", index, co[0], co[1], co[2]);
240 for (x = 0; x < edgeSize; x++) {
241 float *co = EDGE_getCo(e, subdivLevels, x);
242 printf("edge index=%d, seg=%d, co=(%f, %f, %f)\n", index, x, co[0], co[1], co[2]);
243 }
244 co = VERT_getCo(e->v1, subdivLevels);
245 printf("edge index=%d, end_co=(%f, %f, %f)\n", index, co[0], co[1], co[2]);
246 }
247 }
248
249 for (i = 0, index = 0; i < ss->fMap->curSize; i++) {
250 CCGFace *f = (CCGFace *)ss->fMap->buckets[i];
251 for (; f; f = f->next, index++) {
252 for (S = 0; S < f->numVerts; S++) {
253 CCGVert *v = FACE_getVerts(f)[S];
254 float *co = VERT_getCo(v, subdivLevels);
255 printf("face index=%d, vertex=%d, coord=(%f, %f, %f)\n", index, S, co[0], co[1], co[2]);
256 }
257 }
258 }
259
260 for (i = 0, index = 0; i < ss->fMap->curSize; i++) {
261 CCGFace *f = (CCGFace *)ss->fMap->buckets[i];
262 for (; f; f = f->next, index++) {
263 for (S = 0; S < f->numVerts; S++) {
264 CCGEdge *e = FACE_getEdges(f)[S];
265 float *co1 = VERT_getCo(e->v0, subdivLevels);
266 float *co2 = VERT_getCo(e->v1, subdivLevels);
267 printf("face index=%d, edge=%d, coord1=(%f, %f, %f), coord2=(%f, %f, %f)\n",
268 index,
269 S,
270 co1[0],
271 co1[1],
272 co1[2],
273 co2[0],
274 co2[1],
275 co2[2]);
276 }
277 }
278 }
279
280 for (i = 0, index = 0; i < ss->fMap->curSize; i++) {
281 CCGFace *f = (CCGFace *)ss->fMap->buckets[i];
282 for (; f; f = f->next, index++) {
283 for (S = 0; S < f->numVerts; S++) {
284 int x, y;
285 for (x = 0; x < gridSize; x++) {
286 for (y = 0; y < gridSize; y++) {
287 float *co = FACE_getIFCo(f, subdivLevels, S, x, y);
288 printf("face index=%d. corner=%d, x=%d, y=%d, coord=(%f, %f, %f)\n",
289 index,
290 S,
291 x,
292 y,
293 co[0],
294 co[1],
295 co[2]);
296 }
297 }
298 for (x = 0; x < gridSize; x++) {
299 float *co = FACE_getIECo(f, subdivLevels, S, x);
300 printf("face index=%d. corner=%d, ie_index=%d, coord=(%f, %f, %f)\n",
301 index,
302 S,
303 x,
304 co[0],
305 co[1],
306 co[2]);
307 }
308 }
309 }
310 }
311}
312#endif /* DUMP_RESULT_GRIDS */
313
#define UNLIKELY(x)
void * CCGAllocatorHDL
Definition CCGSubSurf.h:30
BLI_INLINE int ccg_edgesize(int level)
BLI_INLINE CCGVert ** FACE_getVerts(CCGFace *f)
BLI_INLINE int ccg_gridsize(int level)
BLI_INLINE CCGEdge ** FACE_getEdges(CCGFace *f)
#define EHASH_alloc(eh, nb)
#define EDGE_getCo(e, lvl, x)
#define FACE_getIFCo(f, lvl, S, x, y)
#define EHASH_free(eh, ptr)
#define VERT_getCo(v, lvl)
void(*)(EHEntry *, void *) EHEntryFreeFP
#define EHASH_hash(eh, item)
#define FACE_getIECo(f, lvl, S, x)
void ccg_ehashIterator_init(EHash *eh, EHashIterator *ehi)
void ccg_ehashIterator_next(EHashIterator *ehi)
void ccg_ehash_insert(EHash *eh, EHEntry *entry)
int ccg_ehashIterator_isStopped(EHashIterator *ehi)
void * ccg_ehash_lookupWithPrev(EHash *eh, void *key, void ***prevp_r)
static int kHashSizes[]
static void _stdAllocator_free(CCGAllocatorHDL, void *ptr)
static void * _stdAllocator_realloc(CCGAllocatorHDL, void *ptr, int newSize, int)
void * ccg_ehashIterator_getCurrent(EHashIterator *ehi)
void ccg_ehash_free(EHash *eh, EHEntryFreeFP freeEntry, void *user_data)
EHash * ccg_ehash_new(int estimatedNumEntries, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator)
CCGAllocatorIFC * ccg_getStandardAllocatorIFC()
static void * _stdAllocator_alloc(CCGAllocatorHDL, int numBytes)
void * ccg_ehash_lookup(EHash *eh, void *key)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define printf(...)
#define MEM_reallocN(vmemh, len)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static ulong * next
#define hash
Definition noise_c.cc:154
void(* free)(CCGAllocatorHDL a, void *ptr)
Definition CCGSubSurf.h:35
void(* release)(CCGAllocatorHDL a)
Definition CCGSubSurf.h:36
void *(* alloc)(CCGAllocatorHDL a, int numBytes)
Definition CCGSubSurf.h:33
void *(* realloc)(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
Definition CCGSubSurf.h:34
int vertDataSize
Definition CCGSubSurf.h:24
CCGMeshIFC meshIFC
struct EHEntry * next
struct EHash * eh
Definition CCGSubSurf.h:41
struct EHEntry * curEntry
Definition CCGSubSurf.h:43
CCGAllocatorHDL allocator
EHEntry ** buckets
CCGAllocatorIFC allocatorIFC
i
Definition text_draw.cc:230
PointerRNA * ptr
Definition wm_files.cc:4227