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