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