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