Blender V4.5
CCGSubSurf.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 "BKE_ccg.hh"
17#include "BKE_subsurf.hh"
18#include "CCGSubSurf.h"
19#include "CCGSubSurf_inline.h"
20#include "CCGSubSurf_intern.h"
21
22/***/
23
24int BKE_ccg_gridsize(int level)
25{
26 return ccg_gridsize(level);
27}
28
29int BKE_ccg_factor(int low_level, int high_level)
30{
31 BLI_assert(low_level > 0 && high_level > 0);
32 BLI_assert(low_level <= high_level);
33
34 return 1 << (high_level - low_level);
35}
36
37/***/
38
40{
41 int num_vert_data = ss->subdivLevels + 1;
42 CCGVert *v = static_cast<CCGVert *>(CCGSUBSURF_alloc(
43 ss, sizeof(CCGVert) + ss->meshIFC.vertDataSize * num_vert_data + ss->meshIFC.vertUserSize));
44 uint8_t *user_data;
45
46 v->vHDL = vHDL;
47 v->edges = nullptr;
48 v->faces = nullptr;
49 v->numEdges = v->numFaces = 0;
50 v->flags = 0;
51
52 user_data = static_cast<uint8_t *>(ccgSubSurf_getVertUserData(ss, v));
53 memset(user_data, 0, ss->meshIFC.vertUserSize);
54 if (ss->useAgeCounts) {
55 *((int *)&user_data[ss->vertUserAgeOffset]) = ss->currentAge;
56 }
57
58 return v;
59}
61{
62 for (int i = 0; i < v->numEdges; i++) {
63 if (v->edges[i] == e) {
64 v->edges[i] = v->edges[--v->numEdges];
65 break;
66 }
67 }
68}
69static void _vert_remFace(CCGVert *v, CCGFace *f)
70{
71 for (int i = 0; i < v->numFaces; i++) {
72 if (v->faces[i] == f) {
73 v->faces[i] = v->faces[--v->numFaces];
74 break;
75 }
76 }
77}
79{
80 v->edges = static_cast<CCGEdge **>(CCGSUBSURF_realloc(
81 ss, v->edges, (v->numEdges + 1) * sizeof(*v->edges), v->numEdges * sizeof(*v->edges)));
82 v->edges[v->numEdges++] = e;
83}
85{
86 v->faces = static_cast<CCGFace **>(CCGSUBSURF_realloc(
87 ss, v->faces, (v->numFaces + 1) * sizeof(*v->faces), v->numFaces * sizeof(*v->faces)));
88 v->faces[v->numFaces++] = f;
89}
90static CCGEdge *_vert_findEdgeTo(const CCGVert *v, const CCGVert *vQ)
91{
92 for (int i = 0; i < v->numEdges; i++) {
93 CCGEdge *e = v->edges[v->numEdges - 1 - i]; /* XXX, note reverse. */
94 if ((e->v0 == v && e->v1 == vQ) || (e->v1 == v && e->v0 == vQ)) {
95 return e;
96 }
97 }
98 return nullptr;
99}
100static void _vert_free(CCGVert *v, CCGSubSurf *ss)
101{
102 if (v->edges) {
103 CCGSUBSURF_free(ss, v->edges);
104 }
105
106 if (v->faces) {
107 CCGSUBSURF_free(ss, v->faces);
108 }
109
110 CCGSUBSURF_free(ss, v);
111}
112
113/***/
114
115static CCGEdge *_edge_new(CCGEdgeHDL eHDL, CCGVert *v0, CCGVert *v1, float crease, CCGSubSurf *ss)
116{
117 int num_edge_data = ccg_edgebase(ss->subdivLevels + 1);
118 CCGEdge *e = static_cast<CCGEdge *>(CCGSUBSURF_alloc(
119 ss, sizeof(CCGEdge) + ss->meshIFC.vertDataSize * num_edge_data + ss->meshIFC.edgeUserSize));
120 uint8_t *user_data;
121
122 e->eHDL = eHDL;
123 e->v0 = v0;
124 e->v1 = v1;
125 e->crease = crease;
126 e->faces = nullptr;
127 e->numFaces = 0;
128 e->flags = 0;
129 _vert_addEdge(v0, e, ss);
130 _vert_addEdge(v1, e, ss);
131
132 user_data = static_cast<uint8_t *>(ccgSubSurf_getEdgeUserData(ss, e));
133 memset(user_data, 0, ss->meshIFC.edgeUserSize);
134 if (ss->useAgeCounts) {
135 *((int *)&user_data[ss->edgeUserAgeOffset]) = ss->currentAge;
136 }
137
138 return e;
139}
141{
142 for (int i = 0; i < e->numFaces; i++) {
143 if (e->faces[i] == f) {
144 e->faces[i] = e->faces[--e->numFaces];
145 break;
146 }
147 }
148}
150{
151 e->faces = static_cast<CCGFace **>(CCGSUBSURF_realloc(
152 ss, e->faces, (e->numFaces + 1) * sizeof(*e->faces), e->numFaces * sizeof(*e->faces)));
153 e->faces[e->numFaces++] = f;
154}
155static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSize)
156{
157 int levelBase = ccg_edgebase(lvl);
158 if (v == e->v0) {
159 return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
160 }
161 return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
162}
163
164static void _edge_free(CCGEdge *e, CCGSubSurf *ss)
165{
166 if (e->faces) {
167 CCGSUBSURF_free(ss, e->faces);
168 }
169
170 CCGSUBSURF_free(ss, e);
171}
173{
174 _vert_remEdge(e->v0, e);
175 _vert_remEdge(e->v1, e);
176 e->v0->flags |= Vert_eEffected;
177 e->v1->flags |= Vert_eEffected;
178 _edge_free(e, ss);
179}
180
182 CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, CCGSubSurf *ss)
183{
184 int maxGridSize = ccg_gridsize(ss->subdivLevels);
185 int num_face_data = (numVerts * maxGridSize + numVerts * maxGridSize * maxGridSize + 1);
186 CCGFace *f = static_cast<CCGFace *>(CCGSUBSURF_alloc(
187 ss,
188 sizeof(CCGFace) + sizeof(CCGVert *) * numVerts + sizeof(CCGEdge *) * numVerts +
189 ss->meshIFC.vertDataSize * num_face_data + ss->meshIFC.faceUserSize));
190 uint8_t *user_data;
191
192 f->numVerts = numVerts;
193 BLI_assert(numVerts > 2);
194 f->fHDL = fHDL;
195 f->flags = 0;
196
197 for (int i = 0; i < numVerts; i++) {
198 FACE_getVerts(f)[i] = verts[i];
199 FACE_getEdges(f)[i] = edges[i];
200 _vert_addFace(verts[i], f, ss);
201 _edge_addFace(edges[i], f, ss);
202 }
203
204 user_data = static_cast<uint8_t *>(ccgSubSurf_getFaceUserData(ss, f));
205 memset(user_data, 0, ss->meshIFC.faceUserSize);
206 if (ss->useAgeCounts) {
207 *((int *)&user_data[ss->faceUserAgeOffset]) = ss->currentAge;
208 }
209
210 return f;
211}
212static void _face_free(CCGFace *f, CCGSubSurf *ss)
213{
214 CCGSUBSURF_free(ss, f);
215}
217{
218 int j;
219 for (j = 0; j < f->numVerts; j++) {
223 }
224 _face_free(f, ss);
225}
226
227/***/
228
230 int subdivLevels,
231 CCGAllocatorIFC *allocatorIFC,
232 CCGAllocatorHDL allocator)
233{
234 if (!allocatorIFC) {
235 allocatorIFC = ccg_getStandardAllocatorIFC();
236 allocator = nullptr;
237 }
238
239 if (subdivLevels < 1) {
240 return nullptr;
241 }
242
243 CCGSubSurf *ss = static_cast<CCGSubSurf *>(allocatorIFC->alloc(allocator, sizeof(*ss)));
244
245 ss->allocatorIFC = *allocatorIFC;
246 ss->allocator = allocator;
247
248 ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
249 ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
250 ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
251
252 ss->meshIFC = *ifc;
253
254 ss->subdivLevels = subdivLevels;
255 ss->numGrids = 0;
256 ss->allowEdgeCreation = 0;
257 ss->defaultCreaseValue = 0;
258 ss->defaultEdgeUserData = nullptr;
259
260 ss->useAgeCounts = 0;
262
263 ss->calcVertNormals = 0;
264 ss->normalDataOffset = 0;
265
266 ss->allocMask = 0;
267
268 ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
269 ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
270
271 ss->currentAge = 0;
272
274
275 ss->oldVMap = ss->oldEMap = ss->oldFMap = nullptr;
276 ss->lenTempArrays = 0;
277 ss->tempVerts = nullptr;
278 ss->tempEdges = nullptr;
279
280 return ss;
281}
282
284{
285 CCGAllocatorIFC allocatorIFC = ss->allocatorIFC;
286 CCGAllocatorHDL allocator = ss->allocator;
287
288 if (ss->syncState) {
292
293 MEM_freeN(ss->tempVerts);
294 MEM_freeN(ss->tempEdges);
295 }
296
297 CCGSUBSURF_free(ss, ss->r);
298 CCGSUBSURF_free(ss, ss->q);
299 if (ss->defaultEdgeUserData) {
301 }
302
306
307 CCGSUBSURF_free(ss, ss);
308
309 if (allocatorIFC.release) {
310 allocatorIFC.release(allocator);
311 }
312}
313
315 int allowEdgeCreation,
316 float defaultCreaseValue,
317 void *defaultUserData)
318{
319 if (ss->defaultEdgeUserData) {
321 }
322
323 ss->allowEdgeCreation = !!allowEdgeCreation;
324 ss->defaultCreaseValue = defaultCreaseValue;
326
327 if (defaultUserData) {
328 memcpy(ss->defaultEdgeUserData, defaultUserData, ss->meshIFC.edgeUserSize);
329 }
330 else {
331 memset(ss->defaultEdgeUserData, 0, ss->meshIFC.edgeUserSize);
332 }
333
334 return eCCGError_None;
335}
337 int *allowEdgeCreation_r,
338 float *defaultCreaseValue_r,
339 void *defaultUserData_r)
340{
341 if (allowEdgeCreation_r) {
342 *allowEdgeCreation_r = ss->allowEdgeCreation;
343 }
344 if (ss->allowEdgeCreation) {
345 if (defaultCreaseValue_r) {
346 *defaultCreaseValue_r = ss->defaultCreaseValue;
347 }
348 if (defaultUserData_r) {
349 memcpy(defaultUserData_r, ss->defaultEdgeUserData, ss->meshIFC.edgeUserSize);
350 }
351 }
352}
353
355{
356 if (subdivisionLevels <= 0) {
358 }
359 if (subdivisionLevels != ss->subdivLevels) {
360 ss->numGrids = 0;
361 ss->subdivLevels = subdivisionLevels;
365 ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
366 ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
367 ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
368 }
369
370 return eCCGError_None;
371}
372
374 int *useAgeCounts_r,
375 int *vertUserOffset_r,
376 int *edgeUserOffset_r,
377 int *faceUserOffset_r)
378{
379 *useAgeCounts_r = ss->useAgeCounts;
380
381 if (vertUserOffset_r) {
382 *vertUserOffset_r = ss->vertUserAgeOffset;
383 }
384 if (edgeUserOffset_r) {
385 *edgeUserOffset_r = ss->edgeUserAgeOffset;
386 }
387 if (faceUserOffset_r) {
388 *faceUserOffset_r = ss->faceUserAgeOffset;
389 }
390}
391
393 CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset)
394{
395 if (useAgeCounts) {
396 if ((vertUserOffset + 4 > ss->meshIFC.vertUserSize) ||
397 (edgeUserOffset + 4 > ss->meshIFC.edgeUserSize) ||
398 (faceUserOffset + 4 > ss->meshIFC.faceUserSize))
399 {
401 }
402 ss->useAgeCounts = 1;
403 ss->vertUserAgeOffset = vertUserOffset;
404 ss->edgeUserAgeOffset = edgeUserOffset;
405 ss->faceUserAgeOffset = faceUserOffset;
406 }
407 else {
408 ss->useAgeCounts = 0;
410 }
411
412 return eCCGError_None;
413}
414
415CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int normalDataOffset)
416{
417 if (useVertNormals) {
418 if (normalDataOffset < 0 || normalDataOffset + 12 > ss->meshIFC.vertDataSize) {
420 }
421 ss->calcVertNormals = 1;
422 ss->normalDataOffset = normalDataOffset;
423 }
424 else {
425 ss->calcVertNormals = 0;
426 ss->normalDataOffset = 0;
427 }
428
429 return eCCGError_None;
430}
431
432void ccgSubSurf_setAllocMask(CCGSubSurf *ss, int allocMask, int maskOffset)
433{
434 ss->allocMask = allocMask;
435 ss->maskDataOffset = maskOffset;
436}
437
438void ccgSubSurf_setNumLayers(CCGSubSurf *ss, int numLayers)
439{
440 ss->meshIFC.numLayers = numLayers;
441}
442
443/***/
444
446{
447 if (ss->syncState != eSyncState_None) {
449 }
450
451 ss->currentAge++;
452
453 ss->oldVMap = ss->vMap;
454 ss->oldEMap = ss->eMap;
455 ss->oldFMap = ss->fMap;
456
457 ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
458 ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
459 ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
460
461 ss->numGrids = 0;
462
463 ss->lenTempArrays = 12;
464 ss->tempVerts = MEM_malloc_arrayN<CCGVert *>(size_t(ss->lenTempArrays), "CCGSubsurf tempVerts");
465 ss->tempEdges = MEM_malloc_arrayN<CCGEdge *>(size_t(ss->lenTempArrays), "CCGSubsurf tempEdges");
466
468
469 return eCCGError_None;
470}
471
473{
474 if (ss->syncState != eSyncState_None) {
476 }
477
478 ss->currentAge++;
479
481
482 return eCCGError_None;
483}
484
486{
487 if (ss->syncState != eSyncState_Partial) {
489 }
490
491 void **prevp;
492 CCGVert *v = static_cast<CCGVert *>(ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp));
493
494 if (!v || v->numFaces || v->numEdges) {
496 }
497
498 *prevp = v->next;
499 _vert_free(v, ss);
500
501 return eCCGError_None;
502}
503
505{
506 if (ss->syncState != eSyncState_Partial) {
508 }
509
510 void **prevp;
511 CCGEdge *e = static_cast<CCGEdge *>(ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp));
512
513 if (!e || e->numFaces) {
515 }
516
517 *prevp = e->next;
519
520 return eCCGError_None;
521}
522
524{
525 if (ss->syncState != eSyncState_Partial) {
527 }
528
529 void **prevp;
530 CCGFace *f = static_cast<CCGFace *>(ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp));
531
532 if (!f) {
534 }
535
536 *prevp = f->next;
538
539 return eCCGError_None;
540}
541
543 CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r)
544{
545 void **prevp;
546 CCGVert *v = nullptr;
547 short seamflag = (seam) ? Vert_eSeam : 0;
548
549 if (ss->syncState == eSyncState_Partial) {
550 v = static_cast<CCGVert *>(ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp));
551 if (!v) {
552 v = _vert_new(vHDL, ss);
553 VertDataCopy(static_cast<float *>(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize)),
554 static_cast<const float *>(vertData),
555 ss);
557 v->flags = Vert_eEffected | seamflag;
558 }
559 else if (!VertDataEqual(
560 static_cast<const float *>(vertData),
561 static_cast<const float *>(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize)),
562 ss) ||
563 ((v->flags & Vert_eSeam) != seamflag))
564 {
565 int i, j;
566
567 VertDataCopy(static_cast<float *>(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize)),
568 static_cast<const float *>(vertData),
569 ss);
570 v->flags = Vert_eEffected | seamflag;
571
572 for (i = 0; i < v->numEdges; i++) {
573 CCGEdge *e = v->edges[i];
574 e->v0->flags |= Vert_eEffected;
575 e->v1->flags |= Vert_eEffected;
576 }
577 for (i = 0; i < v->numFaces; i++) {
578 CCGFace *f = v->faces[i];
579 for (j = 0; j < f->numVerts; j++) {
581 }
582 }
583 }
584 }
585 else {
586 if (ss->syncState != eSyncState_Vert) {
588 }
589
590 v = static_cast<CCGVert *>(ccg_ehash_lookupWithPrev(ss->oldVMap, vHDL, &prevp));
591 if (!v) {
592 v = _vert_new(vHDL, ss);
593 VertDataCopy(static_cast<float *>(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize)),
594 static_cast<const float *>(vertData),
595 ss);
597 v->flags = Vert_eEffected | seamflag;
598 }
599 else if (!VertDataEqual(
600 static_cast<const float *>(vertData),
601 static_cast<const float *>(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize)),
602 ss) ||
603 ((v->flags & Vert_eSeam) != seamflag))
604 {
605 *prevp = v->next;
607 VertDataCopy(static_cast<float *>(ccg_vert_getCo(v, 0, ss->meshIFC.vertDataSize)),
608 static_cast<const float *>(vertData),
609 ss);
610 v->flags = Vert_eEffected | Vert_eChanged | seamflag;
611 }
612 else {
613 *prevp = v->next;
615 v->flags = 0;
616 }
617 }
618
619 if (v_r) {
620 *v_r = v;
621 }
622 return eCCGError_None;
623}
624
626 CCGEdgeHDL eHDL,
627 CCGVertHDL e_vHDL0,
628 CCGVertHDL e_vHDL1,
629 float crease,
630 CCGEdge **e_r)
631{
632 void **prevp;
633 CCGEdge *e = nullptr, *eNew;
634
635 if (ss->syncState == eSyncState_Partial) {
636 e = static_cast<CCGEdge *>(ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp));
637 if (!e || e->v0->vHDL != e_vHDL0 || e->v1->vHDL != e_vHDL1 || crease != e->crease) {
638 CCGVert *v0 = static_cast<CCGVert *>(ccg_ehash_lookup(ss->vMap, e_vHDL0));
639 CCGVert *v1 = static_cast<CCGVert *>(ccg_ehash_lookup(ss->vMap, e_vHDL1));
640
641 eNew = _edge_new(eHDL, v0, v1, crease, ss);
642
643 if (e) {
644 *prevp = eNew;
645 eNew->next = e->next;
646
648 }
649 else {
650 ccg_ehash_insert(ss->eMap, (EHEntry *)eNew);
651 }
652
653 eNew->v0->flags |= Vert_eEffected;
654 eNew->v1->flags |= Vert_eEffected;
655 }
656 }
657 else {
658 if (ss->syncState == eSyncState_Vert) {
660 }
661 else if (ss->syncState != eSyncState_Edge) {
663 }
664
665 e = static_cast<CCGEdge *>(ccg_ehash_lookupWithPrev(ss->oldEMap, eHDL, &prevp));
666 if (!e || e->v0->vHDL != e_vHDL0 || e->v1->vHDL != e_vHDL1 || e->crease != crease) {
667 CCGVert *v0 = static_cast<CCGVert *>(ccg_ehash_lookup(ss->vMap, e_vHDL0));
668 CCGVert *v1 = static_cast<CCGVert *>(ccg_ehash_lookup(ss->vMap, e_vHDL1));
669 e = _edge_new(eHDL, v0, v1, crease, ss);
671 e->v0->flags |= Vert_eEffected;
672 e->v1->flags |= Vert_eEffected;
673 }
674 else {
675 *prevp = e->next;
677 e->flags = 0;
678 if ((e->v0->flags | e->v1->flags) & Vert_eChanged) {
679 e->v0->flags |= Vert_eEffected;
680 e->v1->flags |= Vert_eEffected;
681 }
682 }
683 }
684
685 if (e_r) {
686 *e_r = e;
687 }
688 return eCCGError_None;
689}
690
692 CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r)
693{
694 void **prevp;
695 CCGFace *f = nullptr, *fNew;
696 int j, k, topologyChanged = 0;
697
698 if (UNLIKELY(numVerts > ss->lenTempArrays)) {
699 ss->lenTempArrays = (numVerts < ss->lenTempArrays * 2) ? ss->lenTempArrays * 2 : numVerts;
700 ss->tempVerts = static_cast<CCGVert **>(
701 MEM_reallocN(ss->tempVerts, sizeof(*ss->tempVerts) * ss->lenTempArrays));
702 ss->tempEdges = static_cast<CCGEdge **>(
703 MEM_reallocN(ss->tempEdges, sizeof(*ss->tempEdges) * ss->lenTempArrays));
704 }
705
706 if (ss->syncState == eSyncState_Partial) {
707 f = static_cast<CCGFace *>(ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp));
708
709 for (k = 0; k < numVerts; k++) {
710 ss->tempVerts[k] = static_cast<CCGVert *>(ccg_ehash_lookup(ss->vMap, vHDLs[k]));
711 }
712 for (k = 0; k < numVerts; k++) {
713 ss->tempEdges[k] = _vert_findEdgeTo(ss->tempVerts[k], ss->tempVerts[(k + 1) % numVerts]);
714 }
715
716 if (f) {
717 if (f->numVerts != numVerts ||
718 memcmp(FACE_getVerts(f), ss->tempVerts, sizeof(*ss->tempVerts) * numVerts) != 0 ||
719 memcmp(FACE_getEdges(f), ss->tempEdges, sizeof(*ss->tempEdges) * numVerts) != 0)
720 {
721 topologyChanged = 1;
722 }
723 }
724
725 if (!f || topologyChanged) {
726 fNew = _face_new(fHDL, ss->tempVerts, ss->tempEdges, numVerts, ss);
727
728 if (f) {
729 ss->numGrids += numVerts - f->numVerts;
730
731 *prevp = fNew;
732 fNew->next = f->next;
733
735 }
736 else {
737 ss->numGrids += numVerts;
738 ccg_ehash_insert(ss->fMap, (EHEntry *)fNew);
739 }
740
741 for (k = 0; k < numVerts; k++) {
743 }
744 }
745 }
746 else {
749 }
750 else if (ss->syncState != eSyncState_Face) {
752 }
753
754 f = static_cast<CCGFace *>(ccg_ehash_lookupWithPrev(ss->oldFMap, fHDL, &prevp));
755
756 for (k = 0; k < numVerts; k++) {
757 ss->tempVerts[k] = static_cast<CCGVert *>(ccg_ehash_lookup(ss->vMap, vHDLs[k]));
758
759 if (!ss->tempVerts[k]) {
761 }
762 }
763 for (k = 0; k < numVerts; k++) {
764 ss->tempEdges[k] = _vert_findEdgeTo(ss->tempVerts[k], ss->tempVerts[(k + 1) % numVerts]);
765
766 if (!ss->tempEdges[k]) {
767 if (ss->allowEdgeCreation) {
768 CCGEdge *e = ss->tempEdges[k] = _edge_new((CCGEdgeHDL)-1,
769 ss->tempVerts[k],
770 ss->tempVerts[(k + 1) % numVerts],
772 ss);
774 e->v0->flags |= Vert_eEffected;
775 e->v1->flags |= Vert_eEffected;
776 if (ss->meshIFC.edgeUserSize) {
777 memcpy(ccgSubSurf_getEdgeUserData(ss, e),
780 }
781 }
782 else {
784 }
785 }
786 }
787
788 if (f) {
789 if (f->numVerts != numVerts ||
790 memcmp(FACE_getVerts(f), ss->tempVerts, sizeof(*ss->tempVerts) * numVerts) != 0 ||
791 memcmp(FACE_getEdges(f), ss->tempEdges, sizeof(*ss->tempEdges) * numVerts) != 0)
792 {
793 topologyChanged = 1;
794 }
795 }
796
797 if (!f || topologyChanged) {
798 f = _face_new(fHDL, ss->tempVerts, ss->tempEdges, numVerts, ss);
799 ccg_ehash_insert(ss->fMap, (EHEntry *)f);
800 ss->numGrids += numVerts;
801
802 for (k = 0; k < numVerts; k++) {
804 }
805 }
806 else {
807 *prevp = f->next;
808 ccg_ehash_insert(ss->fMap, (EHEntry *)f);
809 f->flags = 0;
810 ss->numGrids += f->numVerts;
811
812 for (j = 0; j < f->numVerts; j++) {
813 if (FACE_getVerts(f)[j]->flags & Vert_eChanged) {
814 for (k = 0; k < f->numVerts; k++) {
816 }
817 break;
818 }
819 }
820 }
821 }
822
823 if (f_r) {
824 *f_r = f;
825 }
826 return eCCGError_None;
827}
828
830{
832}
833
835{
836 if (ss->syncState == eSyncState_Partial) {
838
840 }
841 else if (ss->syncState) {
845 MEM_freeN(ss->tempEdges);
846 MEM_freeN(ss->tempVerts);
847
848 ss->lenTempArrays = 0;
849
850 ss->oldFMap = ss->oldEMap = ss->oldVMap = nullptr;
851 ss->tempVerts = nullptr;
852 ss->tempEdges = nullptr;
853
855
857 }
858 else {
860 }
861
862 return eCCGError_None;
863}
864
865void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces)
866{
867 CCGFace **array;
868 int i, num;
869
870 if (*faces == nullptr) {
871 array = MEM_malloc_arrayN<CCGFace *>(size_t(ss->fMap->numEntries), "CCGSubsurf allFaces");
872 num = 0;
873 for (i = 0; i < ss->fMap->curSize; i++) {
874 CCGFace *f = (CCGFace *)ss->fMap->buckets[i];
875
876 for (; f; f = f->next) {
877 array[num++] = f;
878 }
879 }
880
881 *faces = array;
882 *numFaces = num;
883 *freeFaces = 1;
884 }
885 else {
886 *freeFaces = 0;
887 }
888}
889
891 CCGFace **faces,
892 int numFaces,
893 CCGVert ***verts,
894 int *numVerts,
895 CCGEdge ***edges,
896 int *numEdges)
897{
898 CCGVert **arrayV;
899 CCGEdge **arrayE;
900 int numV, numE, i, j;
901
902 arrayV = MEM_malloc_arrayN<CCGVert *>(size_t(ss->vMap->numEntries), "CCGSubsurf arrayV");
903 arrayE = MEM_malloc_arrayN<CCGEdge *>(size_t(ss->eMap->numEntries), "CCGSubsurf arrayV");
904 numV = numE = 0;
905
906 for (i = 0; i < numFaces; i++) {
907 CCGFace *f = faces[i];
908 f->flags |= Face_eEffected;
909 }
910
911 for (i = 0; i < ss->vMap->curSize; i++) {
912 CCGVert *v = (CCGVert *)ss->vMap->buckets[i];
913
914 for (; v; v = v->next) {
915 for (j = 0; j < v->numFaces; j++) {
916 if (!(v->faces[j]->flags & Face_eEffected)) {
917 break;
918 }
919 }
920
921 if (j == v->numFaces) {
922 arrayV[numV++] = v;
923 v->flags |= Vert_eEffected;
924 }
925 }
926 }
927
928 for (i = 0; i < ss->eMap->curSize; i++) {
929 CCGEdge *e = (CCGEdge *)ss->eMap->buckets[i];
930
931 for (; e; e = e->next) {
932 for (j = 0; j < e->numFaces; j++) {
933 if (!(e->faces[j]->flags & Face_eEffected)) {
934 break;
935 }
936 }
937
938 if (j == e->numFaces) {
939 e->flags |= Edge_eEffected;
940 arrayE[numE++] = e;
941 }
942 }
943 }
944
945 *verts = arrayV;
946 *numVerts = numV;
947 *edges = arrayE;
948 *numEdges = numE;
949}
950
951CCGError ccgSubSurf_updateFromFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
952{
953 int i, S, x, gridSize, cornerIdx, subdivLevels;
954 int vertDataSize = ss->meshIFC.vertDataSize, freeF;
955
956 subdivLevels = ss->subdivLevels;
957 lvl = (lvl) ? lvl : subdivLevels;
958 gridSize = ccg_gridsize(lvl);
959 cornerIdx = gridSize - 1;
960
961 ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
962
963 for (i = 0; i < numEffectedF; i++) {
964 CCGFace *f = effectedF[i];
965
966 for (S = 0; S < f->numVerts; S++) {
967 CCGEdge *e = FACE_getEdges(f)[S];
968 CCGEdge *prevE = FACE_getEdges(f)[(S + f->numVerts - 1) % f->numVerts];
969
970 VertDataCopy((float *)FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0), ss);
972 VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), ss);
973
974 for (x = 0; x < gridSize; x++) {
975 VertDataCopy(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0), ss);
976 }
977
978 for (x = 0; x < gridSize; x++) {
979 int eI = gridSize - 1 - x;
981 static_cast<float *>(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize)),
982 FACE_getIFCo(f, lvl, S, cornerIdx, x),
983 ss);
984 VertDataCopy(static_cast<float *>(
985 _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize)),
986 FACE_getIFCo(f, lvl, S, x, cornerIdx),
987 ss);
988 }
989 }
990 }
991
992 if (freeF) {
993 MEM_freeN(effectedF);
994 }
995
996 return eCCGError_None;
997}
998
999CCGError ccgSubSurf_updateToFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
1000{
1001 int i, S, x, gridSize, cornerIdx, subdivLevels;
1002 int vertDataSize = ss->meshIFC.vertDataSize, freeF;
1003
1004 subdivLevels = ss->subdivLevels;
1005 lvl = (lvl) ? lvl : subdivLevels;
1006 gridSize = ccg_gridsize(lvl);
1007 cornerIdx = gridSize - 1;
1008
1009 ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
1010
1011 for (i = 0; i < numEffectedF; i++) {
1012 CCGFace *f = effectedF[i];
1013
1014 for (S = 0; S < f->numVerts; S++) {
1015 int prevS = (S + f->numVerts - 1) % f->numVerts;
1016 CCGEdge *e = FACE_getEdges(f)[S];
1017 CCGEdge *prevE = FACE_getEdges(f)[prevS];
1018
1019 for (x = 0; x < gridSize; x++) {
1020 int eI = gridSize - 1 - x;
1021 VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x),
1022 static_cast<const float *>(
1023 _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize)),
1024 ss);
1025 VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx),
1026 static_cast<const float *>(
1027 _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize)),
1028 ss);
1029 }
1030
1031 for (x = 1; x < gridSize - 1; x++) {
1032 VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x), ss);
1033 VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x), ss);
1034 }
1035
1036 VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), (float *)FACE_getCenterData(f), ss);
1038 FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl), ss);
1039 }
1040 }
1041
1042 if (freeF) {
1043 MEM_freeN(effectedF);
1044 }
1045
1046 return eCCGError_None;
1047}
1048
1049CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
1050{
1051 CCGVert **effectedV;
1052 CCGEdge **effectedE;
1053 int numEffectedV, numEffectedE, freeF;
1054 int i, S, x, gridSize, cornerIdx, subdivLevels, edgeSize;
1055 int vertDataSize = ss->meshIFC.vertDataSize;
1056
1057 subdivLevels = ss->subdivLevels;
1058 lvl = (lvl) ? lvl : subdivLevels;
1059 gridSize = ccg_gridsize(lvl);
1060 edgeSize = ccg_edgesize(lvl);
1061 cornerIdx = gridSize - 1;
1062
1063 ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF);
1065 ss, effectedF, numEffectedF, &effectedV, &numEffectedV, &effectedE, &numEffectedE);
1066
1067 /* zero */
1068 for (i = 0; i < numEffectedV; i++) {
1069 CCGVert *v = effectedV[i];
1070 if (v->numFaces) {
1071 VertDataZero(VERT_getCo(v, lvl), ss);
1072 }
1073 }
1074
1075 for (i = 0; i < numEffectedE; i++) {
1076 CCGEdge *e = effectedE[i];
1077
1078 if (e->numFaces) {
1079 for (x = 0; x < edgeSize; x++) {
1080 VertDataZero(EDGE_getCo(e, lvl, x), ss);
1081 }
1082 }
1083 }
1084
1085 /* add */
1086 for (i = 0; i < numEffectedF; i++) {
1087 CCGFace *f = effectedF[i];
1088
1089 VertDataZero((float *)FACE_getCenterData(f), ss);
1090
1091 for (S = 0; S < f->numVerts; S++) {
1092 for (x = 0; x < gridSize; x++) {
1093 VertDataZero(FACE_getIECo(f, lvl, S, x), ss);
1094 }
1095 }
1096
1097 for (S = 0; S < f->numVerts; S++) {
1098 int prevS = (S + f->numVerts - 1) % f->numVerts;
1099 CCGEdge *e = FACE_getEdges(f)[S];
1100 CCGEdge *prevE = FACE_getEdges(f)[prevS];
1101
1102 VertDataAdd((float *)FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0), ss);
1103 if (FACE_getVerts(f)[S]->flags & Vert_eEffected) {
1105 FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx),
1106 ss);
1107 }
1108
1109 for (x = 1; x < gridSize - 1; x++) {
1110 VertDataAdd(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0), ss);
1111 VertDataAdd(FACE_getIECo(f, lvl, prevS, x), FACE_getIFCo(f, lvl, S, 0, x), ss);
1112 }
1113
1114 for (x = 0; x < gridSize - 1; x++) {
1115 int eI = gridSize - 1 - x;
1116 if (FACE_getEdges(f)[S]->flags & Edge_eEffected) {
1118 static_cast<float *>(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize)),
1119 FACE_getIFCo(f, lvl, S, cornerIdx, x),
1120 ss);
1121 }
1122 if (FACE_getEdges(f)[prevS]->flags & Edge_eEffected) {
1123 if (x != 0) {
1124 VertDataAdd(static_cast<float *>(
1125 _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize)),
1126 FACE_getIFCo(f, lvl, S, x, cornerIdx),
1127 ss);
1128 }
1129 }
1130 }
1131 }
1132 }
1133
1134 /* average */
1135 for (i = 0; i < numEffectedV; i++) {
1136 CCGVert *v = effectedV[i];
1137 if (v->numFaces) {
1138 VertDataMulN(VERT_getCo(v, lvl), 1.0f / v->numFaces, ss);
1139 }
1140 }
1141
1142 for (i = 0; i < numEffectedE; i++) {
1143 CCGEdge *e = effectedE[i];
1144
1145 VertDataCopy(EDGE_getCo(e, lvl, 0), VERT_getCo(e->v0, lvl), ss);
1146 VertDataCopy(EDGE_getCo(e, lvl, edgeSize - 1), VERT_getCo(e->v1, lvl), ss);
1147
1148 if (e->numFaces) {
1149 for (x = 1; x < edgeSize - 1; x++) {
1150 VertDataMulN(EDGE_getCo(e, lvl, x), 1.0f / e->numFaces, ss);
1151 }
1152 }
1153 }
1154
1155 /* copy */
1156 for (i = 0; i < numEffectedF; i++) {
1157 CCGFace *f = effectedF[i];
1158
1159 VertDataMulN((float *)FACE_getCenterData(f), 1.0f / f->numVerts, ss);
1160
1161 for (S = 0; S < f->numVerts; S++) {
1162 for (x = 1; x < gridSize - 1; x++) {
1163 VertDataMulN(FACE_getIECo(f, lvl, S, x), 0.5f, ss);
1164 }
1165 }
1166
1167 for (S = 0; S < f->numVerts; S++) {
1168 int prevS = (S + f->numVerts - 1) % f->numVerts;
1169 CCGEdge *e = FACE_getEdges(f)[S];
1170 CCGEdge *prevE = FACE_getEdges(f)[prevS];
1171
1172 VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), (float *)FACE_getCenterData(f), ss);
1174 FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl), ss);
1175
1176 for (x = 1; x < gridSize - 1; x++) {
1177 VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x), ss);
1178 VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x), ss);
1179 }
1180
1181 for (x = 0; x < gridSize - 1; x++) {
1182 int eI = gridSize - 1 - x;
1183
1184 VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x),
1185 static_cast<const float *>(
1186 _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI, vertDataSize)),
1187 ss);
1188 VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx),
1189 static_cast<const float *>(
1190 _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI, vertDataSize)),
1191 ss);
1192 }
1193
1194 VertDataCopy(FACE_getIECo(f, lvl, S, 0), (float *)FACE_getCenterData(f), ss);
1196 FACE_getIECo(f, lvl, S, gridSize - 1), FACE_getIFCo(f, lvl, S, gridSize - 1, 0), ss);
1197 }
1198 }
1199
1200 for (i = 0; i < numEffectedV; i++) {
1201 effectedV[i]->flags = 0;
1202 }
1203 for (i = 0; i < numEffectedE; i++) {
1204 effectedE[i]->flags = 0;
1205 }
1206 for (i = 0; i < numEffectedF; i++) {
1207 effectedF[i]->flags = 0;
1208 }
1209
1210 MEM_freeN(effectedE);
1211 MEM_freeN(effectedV);
1212 if (freeF) {
1213 MEM_freeN(effectedF);
1214 }
1215
1216 return eCCGError_None;
1217}
1218
1219/*** External API accessor functions ***/
1220
1222{
1223 return ss->vMap->numEntries;
1224}
1226{
1227 return ss->eMap->numEntries;
1228}
1230{
1231 return ss->fMap->numEntries;
1232}
1233
1243{
1244 return (CCGFace *)ccg_ehash_lookup(ss->fMap, f);
1245}
1246
1248{
1249 return ss->subdivLevels;
1250}
1252{
1254}
1256{
1257 if (level < 1 || level > ss->subdivLevels) {
1258 return -1;
1259 }
1260 return ccg_edgesize(level);
1261}
1263{
1265}
1267{
1268 if (level < 1 || level > ss->subdivLevels) {
1269 return -1;
1270 }
1271 return ccg_gridsize(level);
1272}
1273
1275{
1276 return ss->meshIFC.simpleSubdiv;
1277}
1278
1279/* Vert accessors */
1280
1282{
1283 return v->vHDL;
1284}
1286{
1287 if (ss->useAgeCounts) {
1288 uint8_t *user_data = static_cast<uint8_t *>(ccgSubSurf_getVertUserData(ss, v));
1289 return ss->currentAge - *((int *)&user_data[ss->vertUserAgeOffset]);
1290 }
1291 return 0;
1292}
1294{
1295 return VERT_getLevelData(v) + ss->meshIFC.vertDataSize * (ss->subdivLevels + 1);
1296}
1298{
1299 return v->numFaces;
1300}
1302{
1303 if (index < 0 || index >= v->numFaces) {
1304 return nullptr;
1305 }
1306 return v->faces[index];
1307}
1309{
1310 return v->numEdges;
1311}
1313{
1314 if (index < 0 || index >= v->numEdges) {
1315 return nullptr;
1316 }
1317 return v->edges[index];
1318}
1324{
1325 if (level < 0 || level > ss->subdivLevels) {
1326 return nullptr;
1327 }
1328 return ccg_vert_getCo(v, level, ss->meshIFC.vertDataSize);
1329}
1330
1331/* Edge accessors */
1332
1334{
1335 return e->eHDL;
1336}
1338{
1339 if (ss->useAgeCounts) {
1340 uint8_t *user_data = static_cast<uint8_t *>(ccgSubSurf_getEdgeUserData(ss, e));
1341 return ss->currentAge - *((int *)&user_data[ss->edgeUserAgeOffset]);
1342 }
1343 return 0;
1344}
1350{
1351 return e->numFaces;
1352}
1354{
1355 if (index < 0 || index >= e->numFaces) {
1356 return nullptr;
1357 }
1358 return e->faces[index];
1359}
1361{
1362 return e->v0;
1363}
1365{
1366 return e->v1;
1367}
1369{
1370 return ccgSubSurf_getEdgeData(ss, e, 0);
1371}
1373{
1374 return ccgSubSurf_getEdgeLevelData(ss, e, x, ss->subdivLevels);
1375}
1377{
1378 if (level < 0 || level > ss->subdivLevels) {
1379 return nullptr;
1380 }
1381 return ccg_edge_getCo(e, level, x, ss->meshIFC.vertDataSize);
1382}
1384{
1385 return e->crease;
1386}
1387
1388/* Face accessors */
1389
1391{
1392 return f->fHDL;
1393}
1395{
1396 if (ss->useAgeCounts) {
1397 uint8_t *user_data = static_cast<uint8_t *>(ccgSubSurf_getFaceUserData(ss, f));
1398 return ss->currentAge - *((int *)&user_data[ss->faceUserAgeOffset]);
1399 }
1400 return 0;
1401}
1403{
1404 int maxGridSize = ccg_gridsize(ss->subdivLevels);
1405 return FACE_getCenterData(f) +
1406 ss->meshIFC.vertDataSize *
1407 (1 + f->numVerts * maxGridSize + f->numVerts * maxGridSize * maxGridSize);
1408}
1410{
1411 return f->numVerts;
1412}
1414{
1415 if (index < 0 || index >= f->numVerts) {
1416 return nullptr;
1417 }
1418 return FACE_getVerts(f)[index];
1419}
1421{
1422 if (index < 0 || index >= f->numVerts) {
1423 return nullptr;
1424 }
1425 return FACE_getEdges(f)[index];
1426}
1428{
1429 for (int i = 0; i < f->numVerts; i++) {
1430 if (FACE_getEdges(f)[i] == e) {
1431 return i;
1432 }
1433 }
1434 return -1;
1435}
1437{
1438 return FACE_getCenterData(f);
1439}
1441{
1442 return ccgSubSurf_getFaceGridEdgeData(ss, f, gridIndex, 0);
1443}
1444void *ccgSubSurf_getFaceGridEdgeData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x)
1445{
1446 return ccg_face_getIECo(
1447 f, ss->subdivLevels, gridIndex, x, ss->subdivLevels, ss->meshIFC.vertDataSize);
1448}
1450{
1451 return ccgSubSurf_getFaceGridData(ss, f, gridIndex, 0, 0);
1452}
1453void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y)
1454{
1455 return ccg_face_getIFCo(
1456 f, ss->subdivLevels, gridIndex, x, y, ss->subdivLevels, ss->meshIFC.vertDataSize);
1457}
1458
1459/*** External API iterator functions ***/
1460
1473
1486
1499
1512
1513/*** External API final vert/edge/face interface. ***/
1514
1516{
1517 int edgeSize = ccg_edgesize(ss->subdivLevels);
1518 int gridSize = ccg_gridsize(ss->subdivLevels);
1519 int numFinalVerts = (ss->vMap->numEntries + ss->eMap->numEntries * (edgeSize - 2) +
1520 ss->fMap->numEntries +
1521 ss->numGrids * ((gridSize - 2) + ((gridSize - 2) * (gridSize - 2))));
1522
1523 return numFinalVerts;
1524}
1526{
1527 int edgeSize = ccg_edgesize(ss->subdivLevels);
1528 int gridSize = ccg_gridsize(ss->subdivLevels);
1529 int numFinalEdges = (ss->eMap->numEntries * (edgeSize - 1) +
1530 ss->numGrids * ((gridSize - 1) + 2 * ((gridSize - 2) * (gridSize - 1))));
1531 return numFinalEdges;
1532}
1534{
1535 int gridSize = ccg_gridsize(ss->subdivLevels);
1536 int numFinalFaces = ss->numGrids * ((gridSize - 1) * (gridSize - 1));
1537 return numFinalFaces;
1538}
1539
1540/***/
1541
1542void CCG_key(CCGKey *key, const CCGSubSurf *ss, int level)
1543{
1544 key->level = level;
1545
1546 key->elem_size = ss->meshIFC.vertDataSize;
1547 key->has_normals = ss->calcVertNormals;
1548
1549 /* if normals are present, always the last three floats of an
1550 * element */
1551 if (key->has_normals) {
1552 key->normal_offset = key->elem_size - sizeof(float[3]);
1553 }
1554 else {
1555 key->normal_offset = -1;
1556 }
1557
1558 key->grid_size = ccgSubSurf_getGridLevelSize(ss, level);
1559 key->grid_area = key->grid_size * key->grid_size;
1560 key->grid_bytes = key->elem_size * key->grid_area;
1561
1562 key->has_mask = ss->allocMask;
1563 if (key->has_mask) {
1564 key->mask_offset = ss->maskDataOffset;
1565 }
1566 else {
1567 key->mask_offset = -1;
1568 }
1569}
1570
1572{
1574}
#define BLI_assert(a)
Definition BLI_assert.h:46
ATTR_WARN_UNUSED_RESULT const size_t num
#define UNLIKELY(x)
#define ELEM(...)
void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter)
static void ccgSubSurf__sync(CCGSubSurf *ss)
int BKE_ccg_gridsize(int level)
Definition CCGSubSurf.cc:24
int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss)
CCGFace * ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f)
int ccgSubSurf_getNumFaces(const CCGSubSurf *ss)
void ccgVertIterator_next(CCGVertIterator *vi)
void CCG_key_top_level(CCGKey *key, const CCGSubSurf *ss)
void CCG_key(CCGKey *key, const CCGSubSurf *ss, int level)
int ccgSubSurf_getVertNumFaces(CCGVert *v)
static void _face_free(CCGFace *f, CCGSubSurf *ss)
int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss)
int ccgSubSurf_getEdgeAge(CCGSubSurf *ss, CCGEdge *e)
void ccgSubSurf__effectedFaceNeighbors(CCGSubSurf *ss, CCGFace **faces, int numFaces, CCGVert ***verts, int *numVerts, CCGEdge ***edges, int *numEdges)
int ccgFaceIterator_isStopped(CCGFaceIterator *fi)
static void _vert_free(CCGVert *v, CCGSubSurf *ss)
CCGSubSurf * ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator)
int ccgEdgeIterator_isStopped(CCGEdgeIterator *ei)
CCGError ccgSubSurf_updateFromFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces)
CCGError ccgSubSurf_setAllowEdgeCreation(CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue, void *defaultUserData)
CCGError ccgSubSurf_updateToFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter)
void ccgSubSurf_setNumLayers(CCGSubSurf *ss, int numLayers)
void * ccgSubSurf_getEdgeUserData(CCGSubSurf *ss, CCGEdge *e)
int ccgSubSurf_getNumVerts(const CCGSubSurf *ss)
void * ccgSubSurf_getFaceUserData(CCGSubSurf *ss, CCGFace *f)
void * ccgSubSurf_getFaceGridEdgeDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex)
void * ccgSubSurf_getVertData(CCGSubSurf *ss, CCGVert *v)
CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r)
static void _vert_remEdge(CCGVert *v, CCGEdge *e)
Definition CCGSubSurf.cc:60
static CCGVert * _vert_new(CCGVertHDL vHDL, CCGSubSurf *ss)
Definition CCGSubSurf.cc:39
static void * _edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSize)
void * ccgSubSurf_getEdgeLevelData(CCGSubSurf *ss, CCGEdge *e, int x, int level)
int ccgSubSurf_getSubdivisionLevels(const CCGSubSurf *ss)
static void _vert_addFace(CCGVert *v, CCGFace *f, CCGSubSurf *ss)
Definition CCGSubSurf.cc:84
static CCGEdge * _edge_new(CCGEdgeHDL eHDL, CCGVert *v0, CCGVert *v1, float crease, CCGSubSurf *ss)
CCGVert * ccgSubSurf_getEdgeVert0(CCGEdge *e)
CCGEdge * ccgSubSurf_getVertEdge(CCGVert *v, int index)
CCGError ccgSubSurf_processSync(CCGSubSurf *ss)
int ccgSubSurf_getVertNumEdges(CCGVert *v)
void * ccgSubSurf_getEdgeData(CCGSubSurf *ss, CCGEdge *e, int x)
static void _edge_free(CCGEdge *e, CCGSubSurf *ss)
void * ccgSubSurf_getVertUserData(CCGSubSurf *ss, CCGVert *v)
CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int normalDataOffset)
int ccgSubSurf_getFaceAge(CCGSubSurf *ss, CCGFace *f)
CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF)
CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r)
void * ccgSubSurf_getVertLevelData(CCGSubSurf *ss, CCGVert *v, int level)
CCGVert * ccgSubSurf_getVert(CCGSubSurf *ss, CCGVertHDL v)
int ccgSubSurf_getSimpleSubdiv(const CCGSubSurf *ss)
void * ccgSubSurf_getFaceGridDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex)
int ccgSubSurf_getGridSize(const CCGSubSurf *ss)
CCGError ccgSubSurf_syncVertDel(CCGSubSurf *ss, CCGVertHDL vHDL)
CCGError ccgSubSurf_syncEdgeDel(CCGSubSurf *ss, CCGEdgeHDL eHDL)
float ccgSubSurf_getEdgeCrease(CCGEdge *e)
CCGFace * ccgSubSurf_getVertFace(CCGVert *v, int index)
CCGError ccgSubSurf_initPartialSync(CCGSubSurf *ss)
CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle(CCGEdge *e)
static void _edge_unlinkMarkAndFree(CCGEdge *e, CCGSubSurf *ss)
static void _face_unlinkMarkAndFree(CCGFace *f, CCGSubSurf *ss)
CCGVert * ccgSubSurf_getEdgeVert1(CCGEdge *e)
void ccgEdgeIterator_next(CCGEdgeIterator *ei)
void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter)
void ccgSubSurf_getUseAgeCounts(CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r)
CCGFaceHDL ccgSubSurf_getFaceFaceHandle(CCGFace *f)
void ccgSubSurf_setAllocMask(CCGSubSurf *ss, int allocMask, int maskOffset)
void ccgSubSurf_free(CCGSubSurf *ss)
CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss)
CCGError ccgSubSurf_setUseAgeCounts(CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset)
CCGVert * ccgVertIterator_getCurrent(CCGVertIterator *vi)
CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL)
CCGEdge * ccgSubSurf_getFaceEdge(CCGFace *f, int index)
void * ccgSubSurf_getEdgeDataArray(CCGSubSurf *ss, CCGEdge *e)
int ccgSubSurf_getNumEdges(const CCGSubSurf *ss)
int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss)
int ccgSubSurf_getEdgeLevelSize(const CCGSubSurf *ss, int level)
void * ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y)
void ccgFaceIterator_next(CCGFaceIterator *fi)
int BKE_ccg_factor(int low_level, int high_level)
Definition CCGSubSurf.cc:29
int ccgVertIterator_isStopped(CCGVertIterator *vi)
CCGEdge * ccgEdgeIterator_getCurrent(CCGEdgeIterator *ei)
static CCGEdge * _vert_findEdgeTo(const CCGVert *v, const CCGVert *vQ)
Definition CCGSubSurf.cc:90
CCGVert * ccgSubSurf_getFaceVert(CCGFace *f, int index)
static void _edge_addFace(CCGEdge *e, CCGFace *f, CCGSubSurf *ss)
int ccgSubSurf_getEdgeNumFaces(CCGEdge *e)
int ccgSubSurf_getEdgeSize(const CCGSubSurf *ss)
static void _vert_remFace(CCGVert *v, CCGFace *f)
Definition CCGSubSurf.cc:69
static void _edge_remFace(CCGEdge *e, CCGFace *f)
CCGEdge * ccgSubSurf_getEdge(CCGSubSurf *ss, CCGEdgeHDL e)
int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level)
CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
int ccgSubSurf_getFaceEdgeIndex(CCGFace *f, CCGEdge *e)
CCGVertHDL ccgSubSurf_getVertVertHandle(CCGVert *v)
static void _vert_addEdge(CCGVert *v, CCGEdge *e, CCGSubSurf *ss)
Definition CCGSubSurf.cc:78
static CCGFace * _face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, CCGSubSurf *ss)
CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r)
CCGFace * ccgFaceIterator_getCurrent(CCGFaceIterator *fi)
void * ccgSubSurf_getFaceCenterData(CCGFace *f)
int ccgSubSurf_getFaceNumVerts(CCGFace *f)
void ccgSubSurf_getAllowEdgeCreation(CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r, void *defaultUserData_r)
void * ccgSubSurf_getFaceGridEdgeData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x)
CCGFace * ccgSubSurf_getEdgeFace(CCGEdge *e, int index)
int ccgSubSurf_getVertAge(CCGSubSurf *ss, CCGVert *v)
EHashIterator CCGFaceIterator
Definition CCGSubSurf.h:202
EHashIterator CCGVertIterator
Definition CCGSubSurf.h:203
void * CCGEdgeHDL
Definition CCGSubSurf.h:13
void * CCGVertHDL
Definition CCGSubSurf.h:12
CCGError
Definition CCGSubSurf.h:48
@ eCCGError_None
Definition CCGSubSurf.h:49
@ eCCGError_InvalidSyncState
Definition CCGSubSurf.h:51
@ eCCGError_InvalidValue
Definition CCGSubSurf.h:52
void * CCGAllocatorHDL
Definition CCGSubSurf.h:30
EHashIterator CCGEdgeIterator
Definition CCGSubSurf.h:201
void * CCGFaceHDL
Definition CCGSubSurf.h:14
BLI_INLINE uint8_t * VERT_getLevelData(CCGVert *v)
BLI_INLINE int ccg_edgesize(int level)
BLI_INLINE uint8_t * EDGE_getLevelData(CCGEdge *e)
BLI_INLINE CCGVert ** FACE_getVerts(CCGFace *f)
BLI_INLINE int ccg_gridsize(int level)
BLI_INLINE void * ccg_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize)
BLI_INLINE void VertDataZero(float v[], const CCGSubSurf *ss)
BLI_INLINE CCGEdge ** FACE_getEdges(CCGFace *f)
BLI_INLINE bool VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss)
BLI_INLINE int ccg_edgebase(int level)
BLI_INLINE void * ccg_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize)
BLI_INLINE uint8_t * FACE_getCenterData(CCGFace *f)
BLI_INLINE void VertDataCopy(float dst[], const float src[], const CCGSubSurf *ss)
BLI_INLINE void * ccg_vert_getCo(CCGVert *v, int lvl, int dataSize)
BLI_INLINE void VertDataMulN(float v[], float f, const CCGSubSurf *ss)
BLI_INLINE void * ccg_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize)
BLI_INLINE void VertDataAdd(float a[], const float b[], const CCGSubSurf *ss)
#define CCGSUBSURF_alloc(ss, nb)
CCGAllocatorIFC * ccg_getStandardAllocatorIFC(void)
void ccg_ehashIterator_init(EHash *eh, EHashIterator *ehi)
void ccg_ehashIterator_next(EHashIterator *ehi)
void ccg_ehash_insert(EHash *eh, EHEntry *entry)
@ Vert_eChanged
@ Vert_eEffected
@ Vert_eSeam
#define EDGE_getCo(e, lvl, x)
int ccg_ehashIterator_isStopped(EHashIterator *ehi)
void * ccg_ehash_lookupWithPrev(EHash *eh, void *key, void ***prevp_r)
#define FACE_getIFCo(f, lvl, S, x, y)
@ Edge_eEffected
@ eSyncState_Edge
@ eSyncState_Vert
@ eSyncState_Face
@ eSyncState_None
@ eSyncState_Partial
void * ccg_ehashIterator_getCurrent(EHashIterator *ehi)
#define VERT_getCo(v, lvl)
#define CCGSUBSURF_free(ss, ptr)
void ccg_ehash_free(EHash *eh, EHEntryFreeFP freeEntry, void *user_data)
#define CCGSUBSURF_realloc(ss, ptr, nb, ob)
void(*)(EHEntry *, void *) EHEntryFreeFP
EHash * ccg_ehash_new(int estimatedNumEntries, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator)
void * ccg_ehash_lookup(EHash *eh, void *key)
@ Face_eEffected
void ccgSubSurf__sync_legacy(CCGSubSurf *ss)
#define FACE_getIECo(f, lvl, S, x)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static float verts[][3]
#define MEM_reallocN(vmemh, len)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static char faces[256]
void(* release)(CCGAllocatorHDL a)
Definition CCGSubSurf.h:36
void *(* alloc)(CCGAllocatorHDL a, int numBytes)
Definition CCGSubSurf.h:33
CCGFace * next
CCGFaceHDL fHDL
int has_mask
Definition BKE_ccg.hh:48
int mask_offset
Definition BKE_ccg.hh:45
int grid_size
Definition BKE_ccg.hh:33
int grid_bytes
Definition BKE_ccg.hh:37
int grid_area
Definition BKE_ccg.hh:35
int level
Definition BKE_ccg.hh:26
int normal_offset
Definition BKE_ccg.hh:41
int elem_size
Definition BKE_ccg.hh:30
int has_normals
Definition BKE_ccg.hh:47
int numLayers
Definition CCGSubSurf.h:23
int vertDataSize
Definition CCGSubSurf.h:24
int simpleSubdiv
Definition CCGSubSurf.h:25
int edgeUserSize
Definition CCGSubSurf.h:22
int faceUserSize
Definition CCGSubSurf.h:22
int vertUserSize
Definition CCGSubSurf.h:22
CCGAllocatorIFC allocatorIFC
void * defaultEdgeUserData
SyncState syncState
CCGMeshIFC meshIFC
CCGEdge ** tempEdges
CCGAllocatorHDL allocator
CCGVert ** tempVerts
EHEntry ** buckets
i
Definition text_draw.cc:230