Blender  V2.93
subsurf_ccg.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  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
25 # ifdef __GNUC__
26 # pragma GCC diagnostic ignored "-Wvla"
27 # endif
28 # define USE_DYNSIZE
29 #endif
30 
31 #include <float.h>
32 #include <math.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #include "atomic_ops.h"
38 
39 #include "MEM_guardedalloc.h"
40 
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
46 
47 #include "BLI_bitmap.h"
48 #include "BLI_blenlib.h"
49 #include "BLI_edgehash.h"
50 #include "BLI_math.h"
51 #include "BLI_memarena.h"
52 #include "BLI_task.h"
53 #include "BLI_threads.h"
54 #include "BLI_utildefines.h"
55 
56 #include "BKE_ccg.h"
57 #include "BKE_cdderivedmesh.h"
58 #include "BKE_mesh.h"
59 #include "BKE_mesh_mapping.h"
60 #include "BKE_modifier.h"
61 #include "BKE_multires.h"
62 #include "BKE_object.h"
63 #include "BKE_paint.h"
64 #include "BKE_pbvh.h"
65 #include "BKE_scene.h"
66 #include "BKE_subsurf.h"
67 
68 #ifndef USE_DYNSIZE
69 # include "BLI_array.h"
70 #endif
71 
72 #include "CCGSubSurf.h"
73 
74 /* assumes MLoop's are laid out 4 for each poly, in order */
75 #define USE_LOOP_LAYOUT_FAST
76 
78  int drawInteriorEdges,
79  int useSubsurfUv,
80  DerivedMesh *dm);
82 
83 static void *arena_alloc(CCGAllocatorHDL a, int numBytes)
84 {
85  return BLI_memarena_alloc(a, numBytes);
86 }
87 
88 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
89 {
90  void *p2 = BLI_memarena_alloc(a, newSize);
91  if (ptr) {
92  memcpy(p2, ptr, oldSize);
93  }
94  return p2;
95 }
96 
98 {
99  /* do nothing */
100 }
101 
103 {
105 }
106 
107 typedef enum {
111  /* add an extra four bytes for a mask layer */
114 } CCGFlags;
115 
116 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLayers, CCGFlags flags)
117 {
118  CCGMeshIFC ifc;
119  CCGSubSurf *ccgSS;
120  int useAging = !!(flags & CCG_USE_AGING);
121  int useArena = flags & CCG_USE_ARENA;
122  int normalOffset = 0;
123 
124  /* (subdivLevels == 0) is not allowed */
125  subdivLevels = MAX2(subdivLevels, 1);
126 
127  if (prevSS) {
128  int oldUseAging;
129 
130  ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
131 
132  if ((oldUseAging != useAging) ||
133  (ccgSubSurf_getSimpleSubdiv(prevSS) != !!(flags & CCG_SIMPLE_SUBDIV))) {
134  ccgSubSurf_free(prevSS);
135  }
136  else {
137  ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
138 
139  return prevSS;
140  }
141  }
142 
143  if (useAging) {
144  ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
145  }
146  else {
147  ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
148  }
149  ifc.numLayers = numLayers;
150  ifc.vertDataSize = sizeof(float) * numLayers;
151  normalOffset += sizeof(float) * numLayers;
152  if (flags & CCG_CALC_NORMALS) {
153  ifc.vertDataSize += sizeof(float[3]);
154  }
155  if (flags & CCG_ALLOC_MASK) {
156  ifc.vertDataSize += sizeof(float);
157  }
158  ifc.simpleSubdiv = !!(flags & CCG_SIMPLE_SUBDIV);
159 
160  if (useArena) {
161  CCGAllocatorIFC allocatorIFC;
162  CCGAllocatorHDL allocator = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "subsurf arena");
163 
164  allocatorIFC.alloc = arena_alloc;
165  allocatorIFC.realloc = arena_realloc;
166  allocatorIFC.free = arena_free;
167  allocatorIFC.release = arena_release;
168 
169  ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
170  }
171  else {
172  ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
173  }
174 
175  if (useAging) {
176  ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
177  }
178 
179  if (flags & CCG_ALLOC_MASK) {
180  normalOffset += sizeof(float);
181  /* mask is allocated after regular layers */
182  ccgSubSurf_setAllocMask(ccgSS, 1, sizeof(float) * numLayers);
183  }
184 
185  if (flags & CCG_CALC_NORMALS) {
186  ccgSubSurf_setCalcVertexNormals(ccgSS, 1, normalOffset);
187  }
188  else {
189  ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0);
190  }
191 
192  return ccgSS;
193 }
194 
195 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize)
196 {
199  int v0idx = *((int *)ccgSubSurf_getVertUserData(ss, v0));
200  int v1idx = *((int *)ccgSubSurf_getVertUserData(ss, v1));
201  int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
202 
203  if (x == 0) {
204  return v0idx;
205  }
206  if (x == edgeSize - 1) {
207  return v1idx;
208  }
209 
210  return edgeBase + x - 1;
211 }
212 
213 static int getFaceIndex(
214  CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize)
215 {
216  int faceBase = *((int *)ccgSubSurf_getFaceUserData(ss, f));
217  int numVerts = ccgSubSurf_getFaceNumVerts(f);
218 
219  if (x == gridSize - 1 && y == gridSize - 1) {
221  return *((int *)ccgSubSurf_getVertUserData(ss, v));
222  }
223  if (x == gridSize - 1) {
226  int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
227  if (v == ccgSubSurf_getEdgeVert0(e)) {
228  return edgeBase + (gridSize - 1 - y) - 1;
229  }
230 
231  return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1);
232  }
233  if (y == gridSize - 1) {
235  CCGEdge *e = ccgSubSurf_getFaceEdge(f, (S + numVerts - 1) % numVerts);
236  int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
237  if (v == ccgSubSurf_getEdgeVert0(e)) {
238  return edgeBase + (gridSize - 1 - x) - 1;
239  }
240 
241  return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1);
242  }
243  if (x == 0 && y == 0) {
244  return faceBase;
245  }
246  if (x == 0) {
247  S = (S + numVerts - 1) % numVerts;
248  return faceBase + 1 + (gridSize - 2) * S + (y - 1);
249  }
250  if (y == 0) {
251  return faceBase + 1 + (gridSize - 2) * S + (x - 1);
252  }
253 
254  return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) +
255  (y - 1) * (gridSize - 2) + (x - 1);
256 }
257 
259  UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts)
260 {
261  UvMapVert *v, *nv;
262  int j, nverts = mpoly[fi].totloop;
263 
264  for (j = 0; j < nverts; j++) {
265  for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v = v->next) {
266  if (v->separate) {
267  nv = v;
268  }
269  if (v->poly_index == fi) {
270  break;
271  }
272  }
273 
274  fverts[j] = POINTER_FROM_UINT(mpoly[nv->poly_index].loopstart + nv->loop_of_poly_index);
275  }
276 }
277 
278 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MLoopUV *mloopuv)
279 {
280  MPoly *mpoly = dm->getPolyArray(dm);
281  MLoop *mloop = dm->getLoopArray(dm);
282  int totvert = dm->getNumVerts(dm);
283  int totface = dm->getNumPolys(dm);
284  int i, seam;
285  UvMapVert *v;
286  UvVertMap *vmap;
287  float limit[2];
288 #ifndef USE_DYNSIZE
289  CCGVertHDL *fverts = NULL;
290  BLI_array_declare(fverts);
291 #endif
292  EdgeSet *eset;
293  float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */
294 
295  limit[0] = limit[1] = STD_UV_CONNECT_LIMIT;
296  /* previous behavior here is without accounting for winding, however this causes stretching in
297  * UV map in really simple cases with mirror + subsurf, see second part of T44530.
298  * Also, initially intention is to treat merged vertices from mirror modifier as seams.
299  * This fixes a very old regression (2.49 was correct here) */
300  vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true);
301  if (!vmap) {
302  return 0;
303  }
304 
306 
307  /* create vertices */
308  for (i = 0; i < totvert; i++) {
309  if (!BKE_mesh_uv_vert_map_get_vert(vmap, i)) {
310  continue;
311  }
312 
313  for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i)->next; v; v = v->next) {
314  if (v->separate) {
315  break;
316  }
317  }
318 
319  seam = (v != NULL);
320 
321  for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) {
322  if (v->separate) {
323  CCGVert *ssv;
324  int loopid = mpoly[v->poly_index].loopstart + v->loop_of_poly_index;
325  CCGVertHDL vhdl = POINTER_FROM_INT(loopid);
326 
327  copy_v2_v2(uv, mloopuv[loopid].uv);
328 
329  ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
330  }
331  }
332  }
333 
334  /* create edges */
335  eset = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totface));
336 
337  for (i = 0; i < totface; i++) {
338  MPoly *mp = &mpoly[i];
339  int nverts = mp->totloop;
340  int j, j_next;
341  CCGFace *origf = ccgSubSurf_getFace(origss, POINTER_FROM_INT(i));
342  /* unsigned int *fv = &mp->v1; */
343  MLoop *ml = mloop + mp->loopstart;
344 
345 #ifdef USE_DYNSIZE
346  CCGVertHDL fverts[nverts];
347 #else
348  BLI_array_clear(fverts);
349  BLI_array_grow_items(fverts, nverts);
350 #endif
351 
352  get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
353 
354  for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) {
355  unsigned int v0 = POINTER_AS_UINT(fverts[j_next]);
356  unsigned int v1 = POINTER_AS_UINT(fverts[j]);
357 
358  if (BLI_edgeset_add(eset, v0, v1)) {
359  CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next);
360  CCGEdgeHDL ehdl = POINTER_FROM_INT(mp->loopstart + j_next);
361  float crease = ccgSubSurf_getEdgeCrease(orige);
362 
363  ccgSubSurf_syncEdge(ss, ehdl, fverts[j_next], fverts[j], crease, &e);
364  }
365  }
366  }
367 
368  BLI_edgeset_free(eset);
369 
370  /* create faces */
371  for (i = 0; i < totface; i++) {
372  MPoly *mp = &mpoly[i];
373  MLoop *ml = &mloop[mp->loopstart];
374  int nverts = mp->totloop;
375  CCGFace *f;
376 
377 #ifdef USE_DYNSIZE
378  CCGVertHDL fverts[nverts];
379 #else
380  BLI_array_clear(fverts);
381  BLI_array_grow_items(fverts, nverts);
382 #endif
383 
384  get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
385  ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), nverts, fverts, &f);
386  }
387 
388 #ifndef USE_DYNSIZE
389  BLI_array_free(fverts);
390 #endif
391 
394 
395  return 1;
396 }
397 
399 {
400  CCGSubSurf *uvss;
401  CCGFace **faceMap;
402  MTFace *tf;
403  MLoopUV *mluv;
404  CCGFaceIterator fi;
405  int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
406  MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
407  /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
408  * just tface except applying the modifier then looses subsurf UV */
409  MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
410  MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n);
411 
412  if (!dmloopuv || (!tface && !mloopuv)) {
413  return;
414  }
415 
416  /* create a CCGSubSurf from uv's */
418 
419  if (!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) {
420  ccgSubSurf_free(uvss);
421  return;
422  }
423 
424  /* get some info from CCGSubSurf */
425  totface = ccgSubSurf_getNumFaces(uvss);
426  /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
427  gridSize = ccgSubSurf_getGridSize(uvss);
428  gridFaces = gridSize - 1;
429 
430  /* make a map from original faces to CCGFaces */
431  faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
433  ccgFaceIterator_next(&fi)) {
436  }
437 
438  /* load coordinates from uvss into tface */
439  tf = tface;
440  mluv = mloopuv;
441 
442  for (index = 0; index < totface; index++) {
443  CCGFace *f = faceMap[index];
444  int numVerts = ccgSubSurf_getFaceNumVerts(f);
445 
446  for (S = 0; S < numVerts; S++) {
447  float(*faceGridData)[2] = ccgSubSurf_getFaceGridDataArray(uvss, f, S);
448 
449  for (y = 0; y < gridFaces; y++) {
450  for (x = 0; x < gridFaces; x++) {
451  float *a = faceGridData[(y + 0) * gridSize + x + 0];
452  float *b = faceGridData[(y + 0) * gridSize + x + 1];
453  float *c = faceGridData[(y + 1) * gridSize + x + 1];
454  float *d = faceGridData[(y + 1) * gridSize + x + 0];
455 
456  if (tf) {
457  copy_v2_v2(tf->uv[0], a);
458  copy_v2_v2(tf->uv[1], d);
459  copy_v2_v2(tf->uv[2], c);
460  copy_v2_v2(tf->uv[3], b);
461  tf++;
462  }
463 
464  if (mluv) {
465  copy_v2_v2(mluv[0].uv, a);
466  copy_v2_v2(mluv[1].uv, d);
467  copy_v2_v2(mluv[2].uv, c);
468  copy_v2_v2(mluv[3].uv, b);
469  mluv += 4;
470  }
471  }
472  }
473  }
474  }
475 
476  ccgSubSurf_free(uvss);
478 }
479 
480 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int layer_index)
481 {
482  set_subsurf_legacy_uv(ss, dm, result, layer_index);
483 }
484 
485 /* face weighting */
486 #define SUB_ELEMS_FACE 50
488 
489 typedef struct FaceVertWeightEntry {
491  float *w;
492  int valid;
494 
495 typedef struct WeightTable {
497  int len;
499 
500 static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
501 {
502  int x, y, i, j;
503  float *w, w1, w2, w4, fac, fac2, fx, fy;
504 
505  if (wtable->len <= faceLen) {
506  void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry) * (faceLen + 1), "weight table alloc 2");
507 
508  if (wtable->len) {
509  memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry) * wtable->len);
510  MEM_freeN(wtable->weight_table);
511  }
512 
513  wtable->weight_table = tmp;
514  wtable->len = faceLen + 1;
515  }
516 
517  if (!wtable->weight_table[faceLen].valid) {
518  wtable->weight_table[faceLen].valid = 1;
519  wtable->weight_table[faceLen].w = w = MEM_callocN(
520  sizeof(float) * faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), "weight table alloc");
521  fac = 1.0f / (float)faceLen;
522 
523  for (i = 0; i < faceLen; i++) {
524  for (x = 0; x < gridCuts + 2; x++) {
525  for (y = 0; y < gridCuts + 2; y++) {
526  fx = 0.5f - (float)x / (float)(gridCuts + 1) / 2.0f;
527  fy = 0.5f - (float)y / (float)(gridCuts + 1) / 2.0f;
528 
529  fac2 = faceLen - 4;
530  w1 = (1.0f - fx) * (1.0f - fy) + (-fac2 * fx * fy * fac);
531  w2 = (1.0f - fx + fac2 * fx * -fac) * (fy);
532  w4 = (fx) * (1.0f - fy + -fac2 * fy * fac);
533 
534  /* these values aren't used for tri's and cause divide by zero */
535  if (faceLen > 3) {
536  fac2 = 1.0f - (w1 + w2 + w4);
537  fac2 = fac2 / (float)(faceLen - 3);
538  for (j = 0; j < faceLen; j++) {
539  w[j] = fac2;
540  }
541  }
542 
543  w[i] = w1;
544  w[(i - 1 + faceLen) % faceLen] = w2;
545  w[(i + 1) % faceLen] = w4;
546 
547  w += faceLen;
548  }
549  }
550  }
551  }
552 
553  return wtable->weight_table[faceLen].w;
554 }
555 
556 static void free_ss_weights(WeightTable *wtable)
557 {
558  int i;
559 
560  for (i = 0; i < wtable->len; i++) {
561  if (wtable->weight_table[i].valid) {
562  MEM_freeN(wtable->weight_table[i].w);
563  }
564  }
565 
566  if (wtable->weight_table) {
567  MEM_freeN(wtable->weight_table);
568  }
569 }
570 
572  DerivedMesh *dm,
573  float (*vertexCos)[3],
574  int useFlatSubdiv)
575 {
576  float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
577 #ifndef USE_DYNSIZE
578  CCGVertHDL *fVerts = NULL;
579  BLI_array_declare(fVerts);
580 #endif
581  MVert *mvert = dm->getVertArray(dm);
582  MEdge *medge = dm->getEdgeArray(dm);
583  /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
584  MVert *mv;
585  MEdge *me;
586  MLoop *mloop = dm->getLoopArray(dm), *ml;
587  MPoly *mpoly = dm->getPolyArray(dm), *mp;
588  /*MFace *mf;*/ /*UNUSED*/
589  int totvert = dm->getNumVerts(dm);
590  int totedge = dm->getNumEdges(dm);
591  /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
592  /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/
593  int i, j;
594  int *index;
595 
597 
598  mv = mvert;
599  index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
600  for (i = 0; i < totvert; i++, mv++) {
601  CCGVert *v;
602 
603  if (vertexCos) {
604  ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), vertexCos[i], 0, &v);
605  }
606  else {
607  ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), mv->co, 0, &v);
608  }
609 
610  ((int *)ccgSubSurf_getVertUserData(ss, v))[1] = (index) ? *index++ : i;
611  }
612 
613  me = medge;
614  index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
615  for (i = 0; i < totedge; i++, me++) {
616  CCGEdge *e;
617  float crease;
618 
619  crease = useFlatSubdiv ? creaseFactor : me->crease * creaseFactor / 255.0f;
620 
622  ss, POINTER_FROM_INT(i), POINTER_FROM_UINT(me->v1), POINTER_FROM_UINT(me->v2), crease, &e);
623 
624  ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index) ? *index++ : i;
625  }
626 
627  mp = mpoly;
628  index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
629  for (i = 0; i < dm->numPolyData; i++, mp++) {
630  CCGFace *f;
631 
632 #ifdef USE_DYNSIZE
633  CCGVertHDL fVerts[mp->totloop];
634 #else
635  BLI_array_clear(fVerts);
636  BLI_array_grow_items(fVerts, mp->totloop);
637 #endif
638 
639  ml = mloop + mp->loopstart;
640  for (j = 0; j < mp->totloop; j++, ml++) {
641  fVerts[j] = POINTER_FROM_UINT(ml->v);
642  }
643 
644  /* this is very bad, means mesh is internally inconsistent.
645  * it is not really possible to continue without modifying
646  * other parts of code significantly to handle missing faces.
647  * since this really shouldn't even be possible we just bail.*/
648  if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), mp->totloop, fVerts, &f) ==
650  static int hasGivenError = 0;
651 
652  if (!hasGivenError) {
653  // XXX error("Unrecoverable error in SubSurf calculation,"
654  // " mesh is inconsistent.");
655 
656  hasGivenError = 1;
657  }
658 
659  return;
660  }
661 
662  ((int *)ccgSubSurf_getFaceUserData(ss, f))[1] = (index) ? *index++ : i;
663  }
664 
666 
667 #ifndef USE_DYNSIZE
668  BLI_array_free(fVerts);
669 #endif
670 }
671 
673  DerivedMesh *dm,
674  float (*vertexCos)[3],
675  int use_flat_subdiv,
676  bool UNUSED(use_subdiv_uvs))
677 {
678  ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
679 }
680 
681 /***/
682 
684 {
685  return ((int *)ccgSubSurf_getVertUserData(ss, v))[1];
686 }
687 
689 {
690  return ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1];
691 }
692 
694 {
695  return ((int *)ccgSubSurf_getFaceUserData(ss, f))[1];
696 }
697 
698 static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3])
699 {
700  if (min[0] > vec[0]) {
701  min[0] = vec[0];
702  }
703  if (min[1] > vec[1]) {
704  min[1] = vec[1];
705  }
706  if (min[2] > vec[2]) {
707  min[2] = vec[2];
708  }
709  if (max[0] < vec[0]) {
710  max[0] = vec[0];
711  }
712  if (max[1] < vec[1]) {
713  max[1] = vec[1];
714  }
715  if (max[2] < vec[2]) {
716  max[2] = vec[2];
717  }
718 }
719 
720 /* UNUSED, keep since this functionality may be useful in the future. */
721 static void UNUSED_FUNCTION(ccgDM_getMinMax)(DerivedMesh *dm, float r_min[3], float r_max[3])
722 {
723  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
724  CCGSubSurf *ss = ccgdm->ss;
725  CCGVertIterator vi;
726  CCGEdgeIterator ei;
727  CCGFaceIterator fi;
728  CCGKey key;
729  int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
730  int gridSize = ccgSubSurf_getGridSize(ss);
731 
732  CCG_key_top_level(&key, ss);
733 
734  if (!ccgSubSurf_getNumVerts(ss)) {
735  r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0;
736  }
737 
739  ccgVertIterator_next(&vi)) {
741  float *co = ccgSubSurf_getVertData(ss, v);
742 
743  minmax_v3_v3v3(co, r_min, r_max);
744  }
745 
747  ccgEdgeIterator_next(&ei)) {
749  CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
750 
751  for (i = 0; i < edgeSize; i++) {
752  minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max);
753  }
754  }
755 
757  ccgFaceIterator_next(&fi)) {
759  int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
760 
761  for (S = 0; S < numVerts; S++) {
762  CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
763 
764  for (y = 0; y < gridSize; y++) {
765  for (x = 0; x < gridSize; x++) {
766  minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max);
767  }
768  }
769  }
770  }
771 }
772 
774 {
775  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
776 
777  return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
778 }
779 
781 {
782  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
783 
784  return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
785 }
786 
788 {
789  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
790 
791  return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
792 }
793 
795 {
796  return dm->numTessFaceData;
797 }
798 
800 {
801  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
802 
803  /* All subsurf faces are quads */
804  return 4 * ccgSubSurf_getNumFinalFaces(ccgdm->ss);
805 }
806 
807 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
808 {
809  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
810  CCGSubSurf *ss = ccgdm->ss;
811  CCGElem *vd;
812  CCGKey key;
813  int i;
814 
815  CCG_key_top_level(&key, ss);
816  memset(mv, 0, sizeof(*mv));
817 
818  if ((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
819  /* this vert comes from face data */
820  int lastface = ccgSubSurf_getNumFaces(ss) - 1;
821  CCGFace *f;
822  int x, y, grid, numVerts;
823  int offset;
824  int gridSize = ccgSubSurf_getGridSize(ss);
825  int gridSideVerts;
826  int gridInternalVerts;
827  int gridSideEnd;
828  int gridInternalEnd;
829 
830  i = 0;
831  while (i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert) {
832  i++;
833  }
834 
835  f = ccgdm->faceMap[i].face;
836  numVerts = ccgSubSurf_getFaceNumVerts(f);
837 
838  gridSideVerts = gridSize - 2;
839  gridInternalVerts = gridSideVerts * gridSideVerts;
840 
841  gridSideEnd = 1 + numVerts * gridSideVerts;
842  gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
843 
844  offset = vertNum - ccgdm->faceMap[i].startVert;
845  if (offset < 1) {
847  copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
848  normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
849  }
850  else if (offset < gridSideEnd) {
851  offset -= 1;
852  grid = offset / gridSideVerts;
853  x = offset % gridSideVerts + 1;
854  vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
855  copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
856  normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
857  }
858  else if (offset < gridInternalEnd) {
859  offset -= gridSideEnd;
860  grid = offset / gridInternalVerts;
861  offset %= gridInternalVerts;
862  y = offset / gridSideVerts + 1;
863  x = offset % gridSideVerts + 1;
864  vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
865  copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
866  normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
867  }
868  }
869  else if ((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
870  /* this vert comes from edge data */
871  CCGEdge *e;
872  int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
873  int x;
874 
875  i = 0;
876  while (i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert) {
877  i++;
878  }
879 
880  e = ccgdm->edgeMap[i].edge;
881 
882  x = vertNum - ccgdm->edgeMap[i].startVert + 1;
883  vd = ccgSubSurf_getEdgeData(ss, e, x);
884  copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
885  normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
886  }
887  else {
888  /* this vert comes from vert data */
889  CCGVert *v;
890  i = vertNum - ccgdm->vertMap[0].startVert;
891 
892  v = ccgdm->vertMap[i].vert;
893  vd = ccgSubSurf_getVertData(ss, v);
894  copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
895  normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
896  }
897 }
898 
899 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float r_co[3])
900 {
901  MVert mvert;
902 
903  ccgDM_getFinalVert(dm, vertNum, &mvert);
904  copy_v3_v3(r_co, mvert.co);
905 }
906 
907 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
908 {
909  MVert mvert;
910 
911  ccgDM_getFinalVert(dm, vertNum, &mvert);
912  normal_short_to_float_v3(r_no, mvert.no);
913 }
914 
915 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
916 {
917  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
918  CCGSubSurf *ss = ccgdm->ss;
919  int i;
920 
921  memset(med, 0, sizeof(*med));
922 
923  if (edgeNum < ccgdm->edgeMap[0].startEdge) {
924  /* this edge comes from face data */
925  int lastface = ccgSubSurf_getNumFaces(ss) - 1;
926  CCGFace *f;
927  int x, y, grid /*, numVerts*/;
928  int offset;
929  int gridSize = ccgSubSurf_getGridSize(ss);
930  int edgeSize = ccgSubSurf_getEdgeSize(ss);
931  int gridSideEdges;
932  int gridInternalEdges;
933 
934  i = 0;
935  while (i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge) {
936  i++;
937  }
938 
939  f = ccgdm->faceMap[i].face;
940  /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
941 
942  gridSideEdges = gridSize - 1;
943  gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
944 
945  offset = edgeNum - ccgdm->faceMap[i].startEdge;
946  grid = offset / (gridSideEdges + gridInternalEdges);
947  offset %= (gridSideEdges + gridInternalEdges);
948 
949  if (offset < gridSideEdges) {
950  x = offset;
951  med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
952  med->v2 = getFaceIndex(ss, f, grid, x + 1, 0, edgeSize, gridSize);
953  }
954  else {
955  offset -= gridSideEdges;
956  x = (offset / 2) / gridSideEdges + 1;
957  y = (offset / 2) % gridSideEdges;
958  if (offset % 2 == 0) {
959  med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
960  med->v2 = getFaceIndex(ss, f, grid, x, y + 1, edgeSize, gridSize);
961  }
962  else {
963  med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
964  med->v2 = getFaceIndex(ss, f, grid, y + 1, x, edgeSize, gridSize);
965  }
966  }
967  }
968  else {
969  /* this vert comes from edge data */
970  CCGEdge *e;
971  int edgeSize = ccgSubSurf_getEdgeSize(ss);
972  int x;
973  short *edgeFlag;
974  unsigned int flags = 0;
975 
976  i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
977 
978  e = ccgdm->edgeMap[i].edge;
979 
981  flags |= ME_LOOSEEDGE;
982  }
983 
984  x = edgeNum - ccgdm->edgeMap[i].startEdge;
985 
986  med->v1 = getEdgeIndex(ss, e, x, edgeSize);
987  med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
988 
989  edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL;
990  if (edgeFlag) {
991  flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER;
992  }
993  else {
994  flags |= ME_EDGEDRAW | ME_EDGERENDER;
995  }
996 
997  med->flag = flags;
998  }
999 }
1000 
1001 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
1002 {
1003  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1004  CCGSubSurf *ss = ccgdm->ss;
1005  int gridSize = ccgSubSurf_getGridSize(ss);
1006  int edgeSize = ccgSubSurf_getEdgeSize(ss);
1007  int gridSideEdges = gridSize - 1;
1008  int gridFaces = gridSideEdges * gridSideEdges;
1009  int i;
1010  CCGFace *f;
1011  /*int numVerts;*/
1012  int offset;
1013  int grid;
1014  int x, y;
1015  /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
1016  DMFlagMat *faceFlags = ccgdm->faceFlags;
1017 
1018  memset(mf, 0, sizeof(*mf));
1019  if (faceNum >= ccgdm->dm.numTessFaceData) {
1020  return;
1021  }
1022 
1023  i = ccgdm->reverseFaceMap[faceNum];
1024 
1025  f = ccgdm->faceMap[i].face;
1026  /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
1027 
1028  offset = faceNum - ccgdm->faceMap[i].startFace;
1029  grid = offset / gridFaces;
1030  offset %= gridFaces;
1031  y = offset / gridSideEdges;
1032  x = offset % gridSideEdges;
1033 
1034  mf->v1 = getFaceIndex(ss, f, grid, x + 0, y + 0, edgeSize, gridSize);
1035  mf->v2 = getFaceIndex(ss, f, grid, x + 0, y + 1, edgeSize, gridSize);
1036  mf->v3 = getFaceIndex(ss, f, grid, x + 1, y + 1, edgeSize, gridSize);
1037  mf->v4 = getFaceIndex(ss, f, grid, x + 1, y + 0, edgeSize, gridSize);
1038 
1039  if (faceFlags) {
1040  mf->flag = faceFlags[i].flag;
1041  mf->mat_nr = faceFlags[i].mat_nr;
1042  }
1043  else {
1044  mf->flag = ME_SMOOTH;
1045  }
1046 
1047  mf->edcode = 0;
1048 }
1049 
1050 /* Translate GridHidden into the ME_HIDE flag for MVerts. Assumes
1051  * vertices are in the order output by ccgDM_copyFinalVertArray. */
1053  const MPoly *mpoly,
1054  MVert *mvert,
1055  const MDisps *mdisps)
1056 {
1057  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1058  CCGSubSurf *ss = ccgdm->ss;
1059  int level = ccgSubSurf_getSubdivisionLevels(ss);
1060  int gridSize = ccgSubSurf_getGridSize(ss);
1061  int edgeSize = ccgSubSurf_getEdgeSize(ss);
1062  int totface = ccgSubSurf_getNumFaces(ss);
1063  int i, j, x, y;
1064 
1065  for (i = 0; i < totface; i++) {
1066  CCGFace *f = ccgdm->faceMap[i].face;
1067 
1068  for (j = 0; j < mpoly[i].totloop; j++) {
1069  const MDisps *md = &mdisps[mpoly[i].loopstart + j];
1070  int hidden_gridsize = BKE_ccg_gridsize(md->level);
1071  int factor = BKE_ccg_factor(level, md->level);
1072  BLI_bitmap *hidden = md->hidden;
1073 
1074  if (!hidden) {
1075  continue;
1076  }
1077 
1078  for (y = 0; y < gridSize; y++) {
1079  for (x = 0; x < gridSize; x++) {
1080  int vndx, offset;
1081 
1082  vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
1083  offset = (y * factor) * hidden_gridsize + (x * factor);
1084  if (BLI_BITMAP_TEST(hidden, offset)) {
1085  mvert[vndx].flag |= ME_HIDE;
1086  }
1087  }
1088  }
1089  }
1090  }
1091 }
1092 
1093 /* Translate GridPaintMask into vertex paint masks. Assumes vertices
1094  * are in the order output by ccgDM_copyFinalVertArray. */
1096  const MPoly *mpoly,
1097  float *paint_mask,
1098  const GridPaintMask *grid_paint_mask)
1099 {
1100  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1101  CCGSubSurf *ss = ccgdm->ss;
1102  int level = ccgSubSurf_getSubdivisionLevels(ss);
1103  int gridSize = ccgSubSurf_getGridSize(ss);
1104  int edgeSize = ccgSubSurf_getEdgeSize(ss);
1105  int totface = ccgSubSurf_getNumFaces(ss);
1106  int i, j, x, y, factor, gpm_gridsize;
1107 
1108  for (i = 0; i < totface; i++) {
1109  CCGFace *f = ccgdm->faceMap[i].face;
1110  const MPoly *p = &mpoly[i];
1111 
1112  for (j = 0; j < p->totloop; j++) {
1113  const GridPaintMask *gpm = &grid_paint_mask[p->loopstart + j];
1114  if (!gpm->data) {
1115  continue;
1116  }
1117 
1118  factor = BKE_ccg_factor(level, gpm->level);
1119  gpm_gridsize = BKE_ccg_gridsize(gpm->level);
1120 
1121  for (y = 0; y < gridSize; y++) {
1122  for (x = 0; x < gridSize; x++) {
1123  int vndx, offset;
1124 
1125  vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
1126  offset = y * factor * gpm_gridsize + x * factor;
1127  paint_mask[vndx] = gpm->data[offset];
1128  }
1129  }
1130  }
1131  }
1132 }
1133 
1134 /* utility function */
1135 BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
1136 {
1137  copy_v3_v3(mv->co, CCG_elem_co(key, elem));
1138  normal_float_to_short_v3(mv->no, CCG_elem_no(key, elem));
1139  mv->flag = mv->bweight = 0;
1140 }
1141 
1143 {
1144  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1145  CCGSubSurf *ss = ccgdm->ss;
1146  CCGElem *vd;
1147  CCGKey key;
1148  int index;
1149  int totvert, totedge, totface;
1150  int gridSize = ccgSubSurf_getGridSize(ss);
1151  int edgeSize = ccgSubSurf_getEdgeSize(ss);
1152  unsigned int i = 0;
1153 
1154  CCG_key_top_level(&key, ss);
1155 
1156  totface = ccgSubSurf_getNumFaces(ss);
1157  for (index = 0; index < totface; index++) {
1158  CCGFace *f = ccgdm->faceMap[index].face;
1159  int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1160 
1162  ccgDM_to_MVert(&mvert[i++], &key, vd);
1163 
1164  for (S = 0; S < numVerts; S++) {
1165  for (x = 1; x < gridSize - 1; x++) {
1166  vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
1167  ccgDM_to_MVert(&mvert[i++], &key, vd);
1168  }
1169  }
1170 
1171  for (S = 0; S < numVerts; S++) {
1172  for (y = 1; y < gridSize - 1; y++) {
1173  for (x = 1; x < gridSize - 1; x++) {
1174  vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
1175  ccgDM_to_MVert(&mvert[i++], &key, vd);
1176  }
1177  }
1178  }
1179  }
1180 
1181  totedge = ccgSubSurf_getNumEdges(ss);
1182  for (index = 0; index < totedge; index++) {
1183  CCGEdge *e = ccgdm->edgeMap[index].edge;
1184  int x;
1185 
1186  for (x = 1; x < edgeSize - 1; x++) {
1187  /* This gives errors with -debug-fpe
1188  * the normals don't seem to be unit length.
1189  * this is most likely caused by edges with no
1190  * faces which are now zerod out, see comment in:
1191  * ccgSubSurf__calcVertNormals(), - campbell */
1192  vd = ccgSubSurf_getEdgeData(ss, e, x);
1193  ccgDM_to_MVert(&mvert[i++], &key, vd);
1194  }
1195  }
1196 
1197  totvert = ccgSubSurf_getNumVerts(ss);
1198  for (index = 0; index < totvert; index++) {
1199  CCGVert *v = ccgdm->vertMap[index].vert;
1200 
1201  vd = ccgSubSurf_getVertData(ss, v);
1202  ccgDM_to_MVert(&mvert[i++], &key, vd);
1203  }
1204 }
1205 
1206 /* utility function */
1207 BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
1208 {
1209  med->v1 = v1;
1210  med->v2 = v2;
1211  med->crease = med->bweight = 0;
1212  med->flag = flag;
1213 }
1214 
1216 {
1217  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1218  CCGSubSurf *ss = ccgdm->ss;
1219  int index;
1220  int totedge, totface;
1221  int gridSize = ccgSubSurf_getGridSize(ss);
1222  int edgeSize = ccgSubSurf_getEdgeSize(ss);
1223  unsigned int i = 0;
1224  short *edgeFlags = ccgdm->edgeFlags;
1225  const short ed_interior_flag = ccgdm->drawInteriorEdges ? (ME_EDGEDRAW | ME_EDGERENDER) : 0;
1226 
1227  totface = ccgSubSurf_getNumFaces(ss);
1228  for (index = 0; index < totface; index++) {
1229  CCGFace *f = ccgdm->faceMap[index].face;
1230  int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1231 
1232  for (S = 0; S < numVerts; S++) {
1233  for (x = 0; x < gridSize - 1; x++) {
1234  ccgDM_to_MEdge(&medge[i++],
1235  getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize),
1236  getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
1237  ed_interior_flag);
1238  }
1239 
1240  for (x = 1; x < gridSize - 1; x++) {
1241  for (y = 0; y < gridSize - 1; y++) {
1242  ccgDM_to_MEdge(&medge[i++],
1243  getFaceIndex(ss, f, S, x, y, edgeSize, gridSize),
1244  getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
1245  ed_interior_flag);
1246  ccgDM_to_MEdge(&medge[i++],
1247  getFaceIndex(ss, f, S, y, x, edgeSize, gridSize),
1248  getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
1249  ed_interior_flag);
1250  }
1251  }
1252  }
1253  }
1254 
1255  totedge = ccgSubSurf_getNumEdges(ss);
1256  for (index = 0; index < totedge; index++) {
1257  CCGEdge *e = ccgdm->edgeMap[index].edge;
1258  short ed_flag = 0;
1259  int x;
1261 
1262  if (!ccgSubSurf_getEdgeNumFaces(e)) {
1263  ed_flag |= ME_LOOSEEDGE;
1264  }
1265 
1266  if (edgeFlags) {
1267  if (edgeIdx != -1) {
1268  ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
1269  }
1270  }
1271  else {
1272  ed_flag |= ME_EDGEDRAW | ME_EDGERENDER;
1273  }
1274 
1275  for (x = 0; x < edgeSize - 1; x++) {
1276  ccgDM_to_MEdge(&medge[i++],
1277  getEdgeIndex(ss, e, x, edgeSize),
1278  getEdgeIndex(ss, e, x + 1, edgeSize),
1279  ed_flag);
1280  }
1281  }
1282 }
1283 
1285 {
1286  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1287  CCGSubSurf *ss = ccgdm->ss;
1288  int index;
1289  int totface;
1290  int gridSize = ccgSubSurf_getGridSize(ss);
1291  int edgeSize = ccgSubSurf_getEdgeSize(ss);
1292  int i = 0;
1293  DMFlagMat *faceFlags = ccgdm->faceFlags;
1294 
1295  totface = dm->getNumTessFaces(dm);
1296  for (index = 0; index < totface; index++) {
1297  CCGFace *f = ccgdm->faceMap[index].face;
1298  int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1299  /* keep types in sync with MFace, avoid many conversions */
1300  char flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
1301  short mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
1302 
1303  for (S = 0; S < numVerts; S++) {
1304  for (y = 0; y < gridSize - 1; y++) {
1305  for (x = 0; x < gridSize - 1; x++) {
1306  MFace *mf = &mface[i];
1307  mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edgeSize, gridSize);
1308  mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edgeSize, gridSize);
1309  mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edgeSize, gridSize);
1310  mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edgeSize, gridSize);
1311  mf->mat_nr = mat_nr;
1312  mf->flag = flag;
1313  mf->edcode = 0;
1314 
1315  i++;
1316  }
1317  }
1318  }
1319  }
1320 }
1321 
1322 typedef struct CopyFinalLoopArrayData {
1328  size_t mloop_index;
1330 
1331 static void copyFinalLoopArray_task_cb(void *__restrict userdata,
1332  const int iter,
1333  const TaskParallelTLS *__restrict UNUSED(tls))
1334 {
1335  CopyFinalLoopArrayData *data = userdata;
1336  CCGDerivedMesh *ccgdm = data->ccgdm;
1337  CCGSubSurf *ss = ccgdm->ss;
1338  const int grid_size = data->grid_size;
1339  const int edge_size = data->edge_size;
1340  CCGFace *f = ccgdm->faceMap[iter].face;
1341  const int num_verts = ccgSubSurf_getFaceNumVerts(f);
1342  const int grid_index = data->grid_offset[iter];
1343  const size_t loop_index = 4 * (size_t)grid_index * (grid_size - 1) * (grid_size - 1);
1344  MLoop *ml = &data->mloop[loop_index];
1345  for (int S = 0; S < num_verts; S++) {
1346  for (int y = 0; y < grid_size - 1; y++) {
1347  for (int x = 0; x < grid_size - 1; x++) {
1348 
1349  uint v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edge_size, grid_size);
1350  uint v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edge_size, grid_size);
1351  uint v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edge_size, grid_size);
1352  uint v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edge_size, grid_size);
1353 
1354  ml->v = v1;
1355  ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
1356  ml++;
1357 
1358  ml->v = v2;
1359  ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
1360  ml++;
1361 
1362  ml->v = v3;
1363  ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
1364  ml++;
1365 
1366  ml->v = v4;
1367  ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
1368  ml++;
1369  }
1370  }
1371  }
1372 }
1373 
1375 {
1376  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1377  CCGSubSurf *ss = ccgdm->ss;
1378 
1379  if (!ccgdm->ehash) {
1381  if (!ccgdm->ehash) {
1382  MEdge *medge;
1383  EdgeHash *ehash;
1384 
1385  ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
1386  medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
1387 
1388  for (int i = 0; i < ccgdm->dm.numEdgeData; i++) {
1389  BLI_edgehash_insert(ehash, medge[i].v1, medge[i].v2, POINTER_FROM_INT(i));
1390  }
1391 
1392  atomic_cas_ptr((void **)&ccgdm->ehash, ccgdm->ehash, ehash);
1393  }
1395  }
1396 
1398  data.ccgdm = ccgdm;
1399  data.mloop = mloop;
1400  data.grid_size = ccgSubSurf_getGridSize(ss);
1401  data.grid_offset = dm->getGridOffset(dm);
1402  data.edge_size = ccgSubSurf_getEdgeSize(ss);
1403 
1404  /* NOTE: For a dense subdivision we've got enough work for each face and
1405  * hence can dedicate whole thread to single face. For less dense
1406  * subdivision we handle multiple faces per thread.
1407  */
1408  data.mloop_index = data.grid_size >= 5 ? 1 : 8;
1409 
1410  TaskParallelSettings settings;
1412  settings.min_iter_per_thread = 1;
1413 
1416 }
1417 
1419 {
1420  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1421  CCGSubSurf *ss = ccgdm->ss;
1422  int index;
1423  int totface;
1424  int gridSize = ccgSubSurf_getGridSize(ss);
1425  /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
1426  int i = 0, k = 0;
1427  DMFlagMat *faceFlags = ccgdm->faceFlags;
1428 
1429  totface = ccgSubSurf_getNumFaces(ss);
1430  for (index = 0; index < totface; index++) {
1431  CCGFace *f = ccgdm->faceMap[index].face;
1432  int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1433  int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
1434  int mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
1435 
1436  for (S = 0; S < numVerts; S++) {
1437  for (y = 0; y < gridSize - 1; y++) {
1438  for (x = 0; x < gridSize - 1; x++) {
1439  MPoly *mp = &mpoly[i];
1440 
1441  mp->mat_nr = mat_nr;
1442  mp->flag = flag;
1443  mp->loopstart = k;
1444  mp->totloop = 4;
1445 
1446  k += 4;
1447  i++;
1448  }
1449  }
1450  }
1451  }
1452 }
1453 
1454 static void ccgDM_release(DerivedMesh *dm)
1455 {
1456  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1457 
1458  if (DM_release(dm)) {
1459  /* Before freeing, need to update the displacement map */
1460  if (ccgdm->multires.modified_flags) {
1461  /* Check that mmd still exists */
1462  if (!ccgdm->multires.local_mmd &&
1463  BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0) {
1464  ccgdm->multires.mmd = NULL;
1465  }
1466 
1467  if (ccgdm->multires.mmd) {
1470  }
1473  }
1474  }
1475  }
1476 
1477  if (ccgdm->ehash) {
1478  BLI_edgehash_free(ccgdm->ehash, NULL);
1479  }
1480 
1481  if (ccgdm->reverseFaceMap) {
1482  MEM_freeN(ccgdm->reverseFaceMap);
1483  }
1484  if (ccgdm->gridFaces) {
1485  MEM_freeN(ccgdm->gridFaces);
1486  }
1487  if (ccgdm->gridData) {
1488  MEM_freeN(ccgdm->gridData);
1489  }
1490  if (ccgdm->gridOffset) {
1491  MEM_freeN(ccgdm->gridOffset);
1492  }
1493  if (ccgdm->gridFlagMats) {
1494  MEM_freeN(ccgdm->gridFlagMats);
1495  }
1496  if (ccgdm->gridHidden) {
1497  /* Using dm->getNumGrids(dm) accesses freed memory */
1498  uint numGrids = ccgdm->numGrid;
1499  for (uint i = 0; i < numGrids; i++) {
1500  if (ccgdm->gridHidden[i]) {
1501  MEM_freeN(ccgdm->gridHidden[i]);
1502  }
1503  }
1504  MEM_freeN(ccgdm->gridHidden);
1505  }
1506  if (ccgdm->freeSS) {
1507  ccgSubSurf_free(ccgdm->ss);
1508  }
1509  if (ccgdm->pmap) {
1510  MEM_freeN(ccgdm->pmap);
1511  }
1512  if (ccgdm->pmap_mem) {
1513  MEM_freeN(ccgdm->pmap_mem);
1514  }
1515  MEM_freeN(ccgdm->edgeFlags);
1516  MEM_freeN(ccgdm->faceFlags);
1517  MEM_freeN(ccgdm->vertMap);
1518  MEM_freeN(ccgdm->edgeMap);
1519  MEM_freeN(ccgdm->faceMap);
1520 
1523 
1524  MEM_freeN(ccgdm);
1525  }
1526 }
1527 
1529 {
1530  if (type == CD_ORIGINDEX) {
1531  /* create origindex on demand to save memory */
1532  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1533  CCGSubSurf *ss = ccgdm->ss;
1534  int *origindex;
1535  int a, index, totnone, totorig;
1536 
1537  /* Avoid re-creation if the layer exists already */
1539  origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1541  if (origindex) {
1542  return origindex;
1543  }
1544 
1547  origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1548 
1549  totorig = ccgSubSurf_getNumVerts(ss);
1550  totnone = dm->numVertData - totorig;
1551 
1552  /* original vertices are at the end */
1553  for (a = 0; a < totnone; a++) {
1554  origindex[a] = ORIGINDEX_NONE;
1555  }
1556 
1557  for (index = 0; index < totorig; index++, a++) {
1558  CCGVert *v = ccgdm->vertMap[index].vert;
1559  origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
1560  }
1562 
1563  return origindex;
1564  }
1565 
1566  return DM_get_vert_data_layer(dm, type);
1567 }
1568 
1570 {
1571  if (type == CD_ORIGINDEX) {
1572  /* create origindex on demand to save memory */
1573  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1574  CCGSubSurf *ss = ccgdm->ss;
1575  int *origindex;
1576  int a, i, index, totnone, totorig, totedge;
1577  int edgeSize = ccgSubSurf_getEdgeSize(ss);
1578 
1579  /* Avoid re-creation if the layer exists already */
1580  origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1581  if (origindex) {
1582  return origindex;
1583  }
1584 
1586  origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1587 
1588  totedge = ccgSubSurf_getNumEdges(ss);
1589  totorig = totedge * (edgeSize - 1);
1590  totnone = dm->numEdgeData - totorig;
1591 
1592  /* original edges are at the end */
1593  for (a = 0; a < totnone; a++) {
1594  origindex[a] = ORIGINDEX_NONE;
1595  }
1596 
1597  for (index = 0; index < totedge; index++) {
1598  CCGEdge *e = ccgdm->edgeMap[index].edge;
1599  int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
1600 
1601  for (i = 0; i < edgeSize - 1; i++, a++) {
1602  origindex[a] = mapIndex;
1603  }
1604  }
1605 
1606  return origindex;
1607  }
1608 
1609  return DM_get_edge_data_layer(dm, type);
1610 }
1611 
1613 {
1614  if (type == CD_ORIGINDEX) {
1615  /* create origindex on demand to save memory */
1616  int *origindex;
1617 
1618  /* Avoid re-creation if the layer exists already */
1619  origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
1620  if (origindex) {
1621  return origindex;
1622  }
1623 
1625  origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
1626 
1627  /* silly loop counting up */
1628  range_vn_i(origindex, dm->getNumTessFaces(dm), 0);
1629 
1630  return origindex;
1631  }
1632 
1633  if (type == CD_TESSLOOPNORMAL) {
1634  /* Create tessloopnormal on demand to save memory. */
1635  /* Note that since tessellated face corners are the same a loops in CCGDM,
1636  * and since all faces have four loops/corners, we can simplify the code
1637  * here by converting tessloopnormals from 'short (*)[4][3]' to 'short (*)[3]'. */
1638  short(*tlnors)[3];
1639 
1640  /* Avoid re-creation if the layer exists already */
1642  if (!tlnors) {
1643  float(*lnors)[3];
1644  short(*tlnors_it)[3];
1645  const int numLoops = ccgDM_getNumLoops(dm);
1646  int i;
1647 
1648  lnors = dm->getLoopDataArray(dm, CD_NORMAL);
1649  if (!lnors) {
1650  return NULL;
1651  }
1652 
1654  tlnors = tlnors_it = (short(*)[3])DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
1655 
1656  /* With ccgdm, we have a simple one to one mapping between loops
1657  * and tessellated face corners. */
1658  for (i = 0; i < numLoops; i++, tlnors_it++, lnors++) {
1659  normal_float_to_short_v3(*tlnors_it, *lnors);
1660  }
1661  }
1662 
1663  return tlnors;
1664  }
1665 
1666  return DM_get_tessface_data_layer(dm, type);
1667 }
1668 
1670 {
1671  if (type == CD_ORIGINDEX) {
1672  /* create origindex on demand to save memory */
1673  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1674  CCGSubSurf *ss = ccgdm->ss;
1675  int *origindex;
1676  int a, i, index, totface;
1677  int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
1678 
1679  /* Avoid re-creation if the layer exists already */
1680  origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
1681  if (origindex) {
1682  return origindex;
1683  }
1684 
1686  origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
1687 
1688  totface = ccgSubSurf_getNumFaces(ss);
1689 
1690  for (a = 0, index = 0; index < totface; index++) {
1691  CCGFace *f = ccgdm->faceMap[index].face;
1692  int numVerts = ccgSubSurf_getFaceNumVerts(f);
1693  int mapIndex = ccgDM_getFaceMapIndex(ss, f);
1694 
1695  for (i = 0; i < gridFaces * gridFaces * numVerts; i++, a++) {
1696  origindex[a] = mapIndex;
1697  }
1698  }
1699 
1700  return origindex;
1701  }
1702 
1703  return DM_get_poly_data_layer(dm, type);
1704 }
1705 
1706 static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type)
1707 {
1708  if (type == CD_ORIGINDEX) {
1709  /* ensure creation of CD_ORIGINDEX layer */
1711  }
1712 
1713  return DM_get_vert_data(dm, index, type);
1714 }
1715 
1716 static void *ccgDM_get_edge_data(DerivedMesh *dm, int index, int type)
1717 {
1718  if (type == CD_ORIGINDEX) {
1719  /* ensure creation of CD_ORIGINDEX layer */
1721  }
1722 
1723  return DM_get_edge_data(dm, index, type);
1724 }
1725 
1726 static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type)
1727 {
1729  /* ensure creation of CD_ORIGINDEX/CD_TESSLOOPNORMAL layers */
1731  }
1732 
1733  return DM_get_tessface_data(dm, index, type);
1734 }
1735 
1736 static void *ccgDM_get_poly_data(DerivedMesh *dm, int index, int type)
1737 {
1738  if (type == CD_ORIGINDEX) {
1739  /* ensure creation of CD_ORIGINDEX layer */
1741  }
1742 
1743  return DM_get_poly_data(dm, index, type);
1744 }
1745 
1747 {
1748  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1749  int index, numFaces, numGrids;
1750 
1751  numFaces = ccgSubSurf_getNumFaces(ccgdm->ss);
1752  numGrids = 0;
1753 
1754  for (index = 0; index < numFaces; index++) {
1755  CCGFace *f = ccgdm->faceMap[index].face;
1756  numGrids += ccgSubSurf_getFaceNumVerts(f);
1757  }
1758 
1759  return numGrids;
1760 }
1761 
1763 {
1764  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1765  return ccgSubSurf_getGridSize(ccgdm->ss);
1766 }
1767 
1769 {
1770  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1771  CCGSubSurf *ss = ccgdm->ss;
1772  CCGElem **gridData;
1773  DMFlagMat *gridFlagMats;
1774  CCGFace **gridFaces;
1775  int *gridOffset;
1776  int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
1777 
1778  if (ccgdm->gridData) {
1779  return;
1780  }
1781 
1782  numGrids = ccgDM_getNumGrids(dm);
1783  numFaces = ccgSubSurf_getNumFaces(ss);
1784  /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/
1785 
1786  /* compute offset into grid array for each face */
1787  gridOffset = MEM_mallocN(sizeof(int) * numFaces, "ccgdm.gridOffset");
1788 
1789  for (gIndex = 0, index = 0; index < numFaces; index++) {
1790  CCGFace *f = ccgdm->faceMap[index].face;
1791  int numVerts = ccgSubSurf_getFaceNumVerts(f);
1792 
1793  gridOffset[index] = gIndex;
1794  gIndex += numVerts;
1795  }
1796 
1797  /* compute grid data */
1798  gridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData");
1799  gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces");
1800  gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats");
1801 
1802  ccgdm->gridHidden = MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden");
1803 
1804  for (gIndex = 0, index = 0; index < numFaces; index++) {
1805  CCGFace *f = ccgdm->faceMap[index].face;
1806  int numVerts = ccgSubSurf_getFaceNumVerts(f);
1807 
1808  for (S = 0; S < numVerts; S++, gIndex++) {
1809  gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1810  gridFaces[gIndex] = f;
1811  gridFlagMats[gIndex] = ccgdm->faceFlags[index];
1812  }
1813  }
1814 
1815  ccgdm->gridData = gridData;
1816  ccgdm->gridFaces = gridFaces;
1817  ccgdm->gridOffset = gridOffset;
1818  ccgdm->gridFlagMats = gridFlagMats;
1819  ccgdm->numGrid = numGrids;
1820 }
1821 
1823 {
1824  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1825 
1826  ccgdm_create_grids(dm);
1827  return ccgdm->gridData;
1828 }
1829 
1831 {
1832  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1833 
1834  ccgdm_create_grids(dm);
1835  return ccgdm->gridOffset;
1836 }
1837 
1838 static void ccgDM_getGridKey(DerivedMesh *dm, CCGKey *key)
1839 {
1840  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1841  CCG_key_top_level(key, ccgdm->ss);
1842 }
1843 
1845 {
1846  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1847 
1848  ccgdm_create_grids(dm);
1849  return ccgdm->gridFlagMats;
1850 }
1851 
1853 {
1854  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1855 
1856  ccgdm_create_grids(dm);
1857  return ccgdm->gridHidden;
1858 }
1859 
1861 {
1862  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1863 
1864  if (!ccgdm->multires.mmd && !ccgdm->pmap && ob->type == OB_MESH) {
1865  Mesh *me = ob->data;
1866 
1868  &ccgdm->pmap_mem,
1869  me->mpoly,
1870  me->mloop,
1871  me->totvert,
1872  me->totpoly,
1873  me->totloop);
1874  }
1875 
1876  return ccgdm->pmap;
1877 }
1878 
1879 /* WARNING! *MUST* be called in an 'loops_cache_rwlock' protected thread context! */
1881 {
1882  MLoopTri *mlooptri = dm->looptris.array;
1883  const int tottri = dm->numPolyData * 2;
1884  int i, poly_index;
1885 
1887  mlooptri = dm->looptris.array_wip;
1888 
1889  BLI_assert(tottri == 0 || mlooptri != NULL);
1891  BLI_assert(tottri == dm->looptris.num);
1892 
1893  for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
1894  MLoopTri *lt;
1895  lt = &mlooptri[i];
1896  /* quad is (0, 3, 2, 1) */
1897  lt->tri[0] = (poly_index * 4) + 0;
1898  lt->tri[1] = (poly_index * 4) + 2;
1899  lt->tri[2] = (poly_index * 4) + 3;
1900  lt->poly = poly_index;
1901 
1902  lt = &mlooptri[i + 1];
1903  lt->tri[0] = (poly_index * 4) + 0;
1904  lt->tri[1] = (poly_index * 4) + 1;
1905  lt->tri[2] = (poly_index * 4) + 2;
1906  lt->poly = poly_index;
1907  }
1908 
1909  BLI_assert(dm->looptris.array == NULL);
1910  atomic_cas_ptr((void **)&dm->looptris.array, dm->looptris.array, dm->looptris.array_wip);
1911  dm->looptris.array_wip = NULL;
1912 }
1913 
1915 {
1916  ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
1917  ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
1918  ccgdm->dm.getNumLoops = ccgDM_getNumLoops;
1919  /* reuse of ccgDM_getNumTessFaces is intentional here:
1920  * subsurf polys are just created from tessfaces */
1921  ccgdm->dm.getNumPolys = ccgDM_getNumPolys;
1923 
1924  ccgdm->dm.getVert = ccgDM_getFinalVert;
1925  ccgdm->dm.getEdge = ccgDM_getFinalEdge;
1927 
1930 
1936 
1945  ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
1946  ccgdm->dm.getGridSize = ccgDM_getGridSize;
1947  ccgdm->dm.getGridData = ccgDM_getGridData;
1949  ccgdm->dm.getGridKey = ccgDM_getGridKey;
1952  ccgdm->dm.getPolyMap = ccgDM_getPolyMap;
1953 
1955 
1956  ccgdm->dm.release = ccgDM_release;
1957 }
1958 
1960 {
1961  CCGVertIterator vi;
1962  CCGEdgeIterator ei;
1963  CCGFaceIterator fi;
1964  int totvert, totedge, totface;
1965 
1966  totvert = ccgSubSurf_getNumVerts(ss);
1967  ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
1969  ccgVertIterator_next(&vi)) {
1971 
1973  }
1974 
1975  totedge = ccgSubSurf_getNumEdges(ss);
1976  ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
1978  ccgEdgeIterator_next(&ei)) {
1980 
1982  }
1983 
1984  totface = ccgSubSurf_getNumFaces(ss);
1985  ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
1987  ccgFaceIterator_next(&fi)) {
1989 
1991  }
1992 }
1993 
1994 /* Fill in all geometry arrays making it possible to access any
1995  * hires data from the CPU.
1996  */
1998  CCGSubSurf *ss,
1999  DerivedMesh *dm,
2000  bool useSubsurfUv)
2001 {
2002  const int totvert = ccgSubSurf_getNumVerts(ss);
2003  const int totedge = ccgSubSurf_getNumEdges(ss);
2004  const int totface = ccgSubSurf_getNumFaces(ss);
2005  int index;
2006  int i;
2007  int vertNum = 0, edgeNum = 0, faceNum = 0;
2008  int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex, *edgeOrigIndex;
2009  short *edgeFlags = ccgdm->edgeFlags;
2010  DMFlagMat *faceFlags = ccgdm->faceFlags;
2011  int *polyidx = NULL;
2012 #ifndef USE_DYNSIZE
2013  int *loopidx = NULL, *vertidx = NULL;
2014  BLI_array_declare(loopidx);
2015  BLI_array_declare(vertidx);
2016 #endif
2017  int loopindex, loopindex2;
2018  int edgeSize;
2019  int gridSize;
2020  int gridFaces, gridCuts;
2021  int gridSideEdges;
2022  int gridInternalEdges;
2023  WeightTable wtable = {NULL};
2024  MEdge *medge = NULL;
2025  MPoly *mpoly = NULL;
2026  bool has_edge_cd;
2027 
2028  edgeSize = ccgSubSurf_getEdgeSize(ss);
2029  gridSize = ccgSubSurf_getGridSize(ss);
2030  gridFaces = gridSize - 1;
2031  gridCuts = gridSize - 2;
2032  /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
2033  gridSideEdges = gridSize - 1;
2034  gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
2035 
2036  /* mvert = dm->getVertArray(dm); */ /* UNUSED */
2037  medge = dm->getEdgeArray(dm);
2038  /* mface = dm->getTessFaceArray(dm); */ /* UNUSED */
2039 
2040  mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2041  base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2042 
2043  vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2044  edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2045 
2046  faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2047  polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2048 
2049  has_edge_cd = ((ccgdm->dm.edgeData.totlayer - (edgeOrigIndex ? 1 : 0)) != 0);
2050 
2051  loopindex = loopindex2 = 0; /* current loop index */
2052  for (index = 0; index < totface; index++) {
2053  CCGFace *f = ccgdm->faceMap[index].face;
2054  int numVerts = ccgSubSurf_getFaceNumVerts(f);
2055  int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2056  int origIndex = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f));
2057  int g2_wid = gridCuts + 2;
2058  float *w, *w2;
2059  int s, x, y;
2060 #ifdef USE_DYNSIZE
2061  int loopidx[numVerts], vertidx[numVerts];
2062 #endif
2063  w = get_ss_weights(&wtable, gridCuts, numVerts);
2064 
2065  ccgdm->faceMap[index].startVert = vertNum;
2066  ccgdm->faceMap[index].startEdge = edgeNum;
2067  ccgdm->faceMap[index].startFace = faceNum;
2068 
2069  faceFlags->flag = mpoly ? mpoly[origIndex].flag : 0;
2070  faceFlags->mat_nr = mpoly ? mpoly[origIndex].mat_nr : 0;
2071  faceFlags++;
2072 
2073  /* set the face base vert */
2074  *((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2075 
2076 #ifndef USE_DYNSIZE
2077  BLI_array_clear(loopidx);
2078  BLI_array_grow_items(loopidx, numVerts);
2079 #endif
2080  for (s = 0; s < numVerts; s++) {
2081  loopidx[s] = loopindex++;
2082  }
2083 
2084 #ifndef USE_DYNSIZE
2085  BLI_array_clear(vertidx);
2086  BLI_array_grow_items(vertidx, numVerts);
2087 #endif
2088  for (s = 0; s < numVerts; s++) {
2089  CCGVert *v = ccgSubSurf_getFaceVert(f, s);
2091  }
2092 
2093  /*I think this is for interpolating the center vert?*/
2094  w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1);
2095  DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
2096  if (vertOrigIndex) {
2097  *vertOrigIndex = ORIGINDEX_NONE;
2098  vertOrigIndex++;
2099  }
2100 
2101  vertNum++;
2102 
2103  /*interpolate per-vert data*/
2104  for (s = 0; s < numVerts; s++) {
2105  for (x = 1; x < gridFaces; x++) {
2106  w2 = w + s * numVerts * g2_wid * g2_wid + x * numVerts;
2107  DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
2108 
2109  if (vertOrigIndex) {
2110  *vertOrigIndex = ORIGINDEX_NONE;
2111  vertOrigIndex++;
2112  }
2113 
2114  vertNum++;
2115  }
2116  }
2117 
2118  /*interpolate per-vert data*/
2119  for (s = 0; s < numVerts; s++) {
2120  for (y = 1; y < gridFaces; y++) {
2121  for (x = 1; x < gridFaces; x++) {
2122  w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
2123  DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
2124 
2125  if (vertOrigIndex) {
2126  *vertOrigIndex = ORIGINDEX_NONE;
2127  vertOrigIndex++;
2128  }
2129 
2130  vertNum++;
2131  }
2132  }
2133  }
2134 
2135  if (edgeOrigIndex) {
2136  for (i = 0; i < numFinalEdges; i++) {
2137  edgeOrigIndex[edgeNum + i] = ORIGINDEX_NONE;
2138  }
2139  }
2140 
2141  for (s = 0; s < numVerts; s++) {
2142  /*interpolate per-face data*/
2143  for (y = 0; y < gridFaces; y++) {
2144  for (x = 0; x < gridFaces; x++) {
2145  w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
2147  &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
2148  loopindex2++;
2149 
2150  w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x)) * numVerts;
2152  &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
2153  loopindex2++;
2154 
2155  w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x + 1)) * numVerts;
2157  &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
2158  loopindex2++;
2159 
2160  w2 = w + s * numVerts * g2_wid * g2_wid + ((y)*g2_wid + (x + 1)) * numVerts;
2162  &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
2163  loopindex2++;
2164 
2165  /*copy over poly data, e.g. mtexpoly*/
2166  CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
2167 
2168  /*set original index data*/
2169  if (faceOrigIndex) {
2170  /* reference the index in 'polyOrigIndex' */
2171  *faceOrigIndex = faceNum;
2172  faceOrigIndex++;
2173  }
2174  if (polyOrigIndex) {
2175  *polyOrigIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
2176  polyOrigIndex++;
2177  }
2178 
2179  ccgdm->reverseFaceMap[faceNum] = index;
2180 
2181  /* This is a simple one to one mapping, here... */
2182  if (polyidx) {
2183  polyidx[faceNum] = faceNum;
2184  }
2185 
2186  faceNum++;
2187  }
2188  }
2189  }
2190 
2191  edgeNum += numFinalEdges;
2192  }
2193 
2194  for (index = 0; index < totedge; index++) {
2195  CCGEdge *e = ccgdm->edgeMap[index].edge;
2196  int numFinalEdges = edgeSize - 1;
2197  int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
2198  int x;
2199  int vertIdx[2];
2201 
2202  CCGVert *v;
2207 
2208  ccgdm->edgeMap[index].startVert = vertNum;
2209  ccgdm->edgeMap[index].startEdge = edgeNum;
2210 
2211  if (edgeIdx >= 0 && edgeFlags) {
2212  edgeFlags[edgeIdx] = medge[edgeIdx].flag;
2213  }
2214 
2215  /* set the edge base vert */
2216  *((int *)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2217 
2218  for (x = 1; x < edgeSize - 1; x++) {
2219  float w[2];
2220  w[1] = (float)x / (edgeSize - 1);
2221  w[0] = 1 - w[1];
2222  DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2223  if (vertOrigIndex) {
2224  *vertOrigIndex = ORIGINDEX_NONE;
2225  vertOrigIndex++;
2226  }
2227  vertNum++;
2228  }
2229 
2230  if (has_edge_cd) {
2231  BLI_assert(edgeIdx >= 0 && edgeIdx < dm->getNumEdges(dm));
2232  for (i = 0; i < numFinalEdges; i++) {
2233  CustomData_copy_data(&dm->edgeData, &ccgdm->dm.edgeData, edgeIdx, edgeNum + i, 1);
2234  }
2235  }
2236 
2237  if (edgeOrigIndex) {
2238  for (i = 0; i < numFinalEdges; i++) {
2239  edgeOrigIndex[edgeNum + i] = mapIndex;
2240  }
2241  }
2242 
2243  edgeNum += numFinalEdges;
2244  }
2245 
2246  if (useSubsurfUv) {
2247  CustomData *ldata = &ccgdm->dm.loopData;
2248  CustomData *dmldata = &dm->loopData;
2249  int numlayer = CustomData_number_of_layers(ldata, CD_MLOOPUV);
2250  int dmnumlayer = CustomData_number_of_layers(dmldata, CD_MLOOPUV);
2251 
2252  for (i = 0; i < numlayer && i < dmnumlayer; i++) {
2253  set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2254  }
2255  }
2256 
2257  for (index = 0; index < totvert; index++) {
2258  CCGVert *v = ccgdm->vertMap[index].vert;
2259  int mapIndex = ccgDM_getVertMapIndex(ccgdm->ss, v);
2260  int vertIdx;
2261 
2263 
2264  ccgdm->vertMap[index].startVert = vertNum;
2265 
2266  /* set the vert base vert */
2267  *((int *)ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2268 
2269  DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2270 
2271  if (vertOrigIndex) {
2272  *vertOrigIndex = mapIndex;
2273  vertOrigIndex++;
2274  }
2275  vertNum++;
2276  }
2277 
2278 #ifndef USE_DYNSIZE
2279  BLI_array_free(vertidx);
2280  BLI_array_free(loopidx);
2281 #endif
2282  free_ss_weights(&wtable);
2283 
2284  BLI_assert(vertNum == ccgSubSurf_getNumFinalVerts(ss));
2285  BLI_assert(edgeNum == ccgSubSurf_getNumFinalEdges(ss));
2286  BLI_assert(loopindex2 == ccgSubSurf_getNumFinalFaces(ss) * 4);
2287  BLI_assert(faceNum == ccgSubSurf_getNumFinalFaces(ss));
2288 }
2289 
2291  int drawInteriorEdges,
2292  int useSubsurfUv,
2293  DerivedMesh *dm)
2294 {
2295  const int totedge = ccgSubSurf_getNumEdges(ss);
2296  const int totface = ccgSubSurf_getNumFaces(ss);
2297  CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2298 
2299  BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
2300  BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
2301  DM_from_template(&ccgdm->dm,
2302  dm,
2303  DM_TYPE_CCGDM,
2306  0,
2309 
2311 
2312  ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
2313  "reverseFaceMap");
2314 
2315  create_ccgdm_maps(ccgdm, ss);
2316 
2318 
2319  ccgdm->ss = ss;
2320  ccgdm->drawInteriorEdges = drawInteriorEdges;
2321  ccgdm->useSubsurfUv = useSubsurfUv;
2322 
2323  /* CDDM hack. */
2324  ccgdm->edgeFlags = MEM_callocN(sizeof(short) * totedge, "edgeFlags");
2325  ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags");
2326 
2327  set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0);
2328 
2332  ccgdm->dm.numLoopData = ccgdm->dm.numPolyData * 4;
2333  ccgdm->dm.numTessFaceData = 0;
2334 
2337 
2338  return ccgdm;
2339 }
2340 
2341 /***/
2342 
2344  struct SubsurfModifierData *smd,
2345  const struct Scene *scene,
2346  float (*vertCos)[3],
2347  SubsurfFlags flags)
2348 {
2349  const int useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : 0;
2350  const CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : 0;
2351  const int useSubsurfUv = (smd->uv_smooth != SUBSURF_UV_SMOOTH_NONE);
2352  const int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2353  const bool ignore_simplify = (flags & SUBSURF_IGNORE_SIMPLIFY);
2355 
2356  /* note: editmode calculation can only run once per
2357  * modifier stack evaluation (uses freed cache) T36299. */
2358  if (flags & SUBSURF_FOR_EDIT_MODE) {
2359  int levels = (scene != NULL && !ignore_simplify) ?
2360  get_render_subsurf_level(&scene->r, smd->levels, false) :
2361  smd->levels;
2362 
2363  /* TODO(sergey): Same as emCache below. */
2364  if ((flags & SUBSURF_IN_EDIT_MODE) && smd->mCache) {
2365  ccgSubSurf_free(smd->mCache);
2366  smd->mCache = NULL;
2367  }
2368 
2369  smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
2370 
2371  ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv);
2372  result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm);
2373  }
2374  else if (flags & SUBSURF_USE_RENDER_PARAMS) {
2375  /* Do not use cache in render mode. */
2376  CCGSubSurf *ss;
2377  int levels = (scene != NULL && !ignore_simplify) ?
2378  get_render_subsurf_level(&scene->r, smd->renderLevels, true) :
2379  smd->renderLevels;
2380 
2381  if (levels == 0) {
2382  return dm;
2383  }
2384 
2385  ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS);
2386 
2387  ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
2388 
2389  result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2390 
2391  result->freeSS = 1;
2392  }
2393  else {
2394  int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2395  int levels = (scene != NULL && !ignore_simplify) ?
2396  get_render_subsurf_level(&scene->r, smd->levels, false) :
2397  smd->levels;
2398  CCGSubSurf *ss;
2399 
2400  /* It is quite possible there is a much better place to do this. It
2401  * depends a bit on how rigorously we expect this function to never
2402  * be called in editmode. In semi-theory we could share a single
2403  * cache, but the handles used inside and outside editmode are not
2404  * the same so we would need some way of converting them. Its probably
2405  * not worth the effort. But then why am I even writing this long
2406  * comment that no one will read? Hmmm. - zr
2407  *
2408  * Addendum: we can't really ensure that this is never called in edit
2409  * mode, so now we have a parameter to verify it. - brecht
2410  */
2411  if (!(flags & SUBSURF_IN_EDIT_MODE) && smd->emCache) {
2412  ccgSubSurf_free(smd->emCache);
2413  smd->emCache = NULL;
2414  }
2415 
2416  if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) {
2417  smd->mCache = ss = _getSubSurf(
2418  smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
2419 
2420  ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
2421 
2422  result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, useSubsurfUv, dm);
2423  }
2424  else {
2425  CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS;
2426  CCGSubSurf *prevSS = NULL;
2427 
2428  if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
2429  ccgSubSurf_free(smd->mCache);
2430  smd->mCache = NULL;
2431  }
2432 
2433  if (flags & SUBSURF_ALLOC_PAINT_MASK) {
2434  ccg_flags |= CCG_ALLOC_MASK;
2435  }
2436 
2437  ss = _getSubSurf(prevSS, levels, 3, ccg_flags);
2438  ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
2439 
2440  result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2441 
2442  if (flags & SUBSURF_IS_FINAL_CALC) {
2443  smd->mCache = ss;
2444  }
2445  else {
2446  result->freeSS = 1;
2447  }
2448 
2449  if (flags & SUBSURF_ALLOC_PAINT_MASK) {
2450  ccgSubSurf_setNumLayers(ss, 4);
2451  }
2452  }
2453  }
2454 
2455  return (DerivedMesh *)result;
2456 }
2457 
2458 void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
2459 {
2460  /* Finds the subsurf limit positions for the verts in a mesh
2461  * and puts them in an array of floats. Please note that the
2462  * calculated vert positions is incorrect for the verts
2463  * on the boundary of the mesh.
2464  */
2465  CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA);
2466  float edge_sum[3], face_sum[3];
2467  CCGVertIterator vi;
2468  DerivedMesh *dm = CDDM_from_mesh(me);
2469 
2470  ss_sync_from_derivedmesh(ss, dm, NULL, 0, 0);
2471 
2473  ccgVertIterator_next(&vi)) {
2477  int numFaces = ccgSubSurf_getVertNumFaces(v);
2478  float *co;
2479  int i;
2480 
2481  zero_v3(edge_sum);
2482  zero_v3(face_sum);
2483 
2484  for (i = 0; i < N; i++) {
2486  add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2487  }
2488  for (i = 0; i < numFaces; i++) {
2489  CCGFace *f = ccgSubSurf_getVertFace(v, i);
2491  }
2492 
2493  /* ad-hoc correction for boundary vertices, to at least avoid them
2494  * moving completely out of place (brecht) */
2495  if (numFaces && numFaces != N) {
2496  mul_v3_fl(face_sum, (float)N / (float)numFaces);
2497  }
2498 
2499  co = ccgSubSurf_getVertData(ss, v);
2500  r_positions[idx][0] = (co[0] * N * N + edge_sum[0] * 4 + face_sum[0]) / (N * (N + 5));
2501  r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5));
2502  r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5));
2503  }
2504 
2505  ccgSubSurf_free(ss);
2506 
2507  dm->release(dm);
2508 }
2509 
2511 {
2512  return dm->getNumEdges(dm) != 0;
2513 }
2514 
2516 {
2517  return dm->getNumPolys(dm) != 0;
2518 }
typedef float(TangentPoint)[2]
void * DM_get_edge_data_layer(struct DerivedMesh *dm, int type)
Definition: DerivedMesh.cc:626
void DM_interp_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest, int *src_indices, float *weights, int count, int dest_index)
Definition: DerivedMesh.cc:665
void DM_copy_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest, int source_index, int dest_index, int count)
Definition: DerivedMesh.cc:654
void * DM_get_poly_data_layer(struct DerivedMesh *dm, int type)
Definition: DerivedMesh.cc:644
void DM_add_vert_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
Definition: DerivedMesh.cc:568
void * DM_get_edge_data(struct DerivedMesh *dm, int index, int type)
Definition: DerivedMesh.cc:599
void * DM_get_vert_data(struct DerivedMesh *dm, int index, int type)
Definition: DerivedMesh.cc:593
void * DM_get_poly_data(struct DerivedMesh *dm, int index, int type)
Definition: DerivedMesh.cc:611
void * DM_get_tessface_data_layer(struct DerivedMesh *dm, int type)
Definition: DerivedMesh.cc:635
bool DM_release(DerivedMesh *dm)
Definition: DerivedMesh.cc:424
void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
Definition: DerivedMesh.cc:404
void DM_ensure_looptri_data(DerivedMesh *dm)
Definition: DerivedMesh.cc:493
void * DM_get_tessface_data(struct DerivedMesh *dm, int index, int type)
Definition: DerivedMesh.cc:605
void * DM_get_vert_data_layer(struct DerivedMesh *dm, int type)
Definition: DerivedMesh.cc:617
void DM_add_tessface_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
Definition: DerivedMesh.cc:578
void DM_add_edge_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
Definition: DerivedMesh.cc:573
@ DM_TYPE_CCGDM
void DM_add_poly_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer)
Definition: DerivedMesh.cc:588
void CCG_key_top_level(CCGKey *key, const struct CCGSubSurf *ss)
BLI_INLINE float * CCG_grid_elem_co(const CCGKey *key, CCGElem *elem, int x, int y)
Definition: BKE_ccg.h:130
BLI_INLINE float * CCG_elem_no(const CCGKey *key, CCGElem *elem)
Definition: BKE_ccg.h:107
struct CCGElem CCGElem
Definition: BKE_ccg.h:46
BLI_INLINE float * CCG_elem_offset_co(const CCGKey *key, CCGElem *elem, int offset)
Definition: BKE_ccg.h:145
BLI_INLINE float * CCG_elem_co(const CCGKey *key, CCGElem *elem)
struct DerivedMesh * CDDM_from_mesh(struct Mesh *mesh)
bool CustomData_free_layer_active(struct CustomData *data, int type, int totelem)
Definition: customdata.c:2707
int CustomData_number_of_layers(const struct CustomData *data, int type)
@ CD_CALLOC
void CustomData_interp(const struct CustomData *source, struct CustomData *dest, const int *src_indices, const float *weights, const float *sub_weights, int count, int dest_index)
#define ORIGINDEX_NONE
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
void * CustomData_get_layer(const struct CustomData *data, int type)
void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count)
UvMapVert * BKE_mesh_uv_vert_map_get_vert(UvVertMap *vmap, unsigned int v)
Definition: mesh_mapping.c:179
void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem, const struct MPoly *mpoly, const struct MLoop *mloop, int totvert, int totpoly, int totloop)
void BKE_mesh_uv_vert_map_free(UvVertMap *vmap)
Definition: mesh_mapping.c:184
UvVertMap * BKE_mesh_uv_vert_map_create(const struct MPoly *mpoly, const struct MLoop *mloop, const struct MLoopUV *mloopuv, unsigned int totpoly, unsigned int totvert, const float limit[2], const bool selected, const bool use_winding)
#define STD_UV_CONNECT_LIMIT
void multires_modifier_update_mdisps(struct DerivedMesh *dm, struct Scene *scene)
Definition: multires.c:1046
void multires_modifier_update_hidden(struct DerivedMesh *dm)
Definition: multires.c:1173
General operations, lookup, etc. for blender objects.
A BVH for high poly meshes.
int get_render_subsurf_level(const struct RenderData *r, int lvl, bool for_render)
int BKE_ccg_gridsize(int level)
Definition: CCGSubSurf.c:37
@ MULTIRES_HIDDEN_MODIFIED
Definition: BKE_subsurf.h:94
@ MULTIRES_COORDS_MODIFIED
Definition: BKE_subsurf.h:92
SubsurfFlags
Definition: BKE_subsurf.h:51
@ SUBSURF_FOR_EDIT_MODE
Definition: BKE_subsurf.h:54
@ SUBSURF_IN_EDIT_MODE
Definition: BKE_subsurf.h:55
@ SUBSURF_ALLOC_PAINT_MASK
Definition: BKE_subsurf.h:56
@ SUBSURF_USE_RENDER_PARAMS
Definition: BKE_subsurf.h:52
@ SUBSURF_IS_FINAL_CALC
Definition: BKE_subsurf.h:53
@ SUBSURF_IGNORE_SIMPLIFY
Definition: BKE_subsurf.h:58
int BKE_ccg_factor(int low_level, int high_level)
Definition: CCGSubSurf.c:42
A (mainly) macro array library.
#define BLI_array_grow_items(arr, num)
Definition: BLI_array.h:99
#define BLI_array_declare(arr)
Definition: BLI_array.h:62
#define BLI_array_clear(arr)
Definition: BLI_array.h:130
#define BLI_array_free(arr)
Definition: BLI_array.h:116
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:63
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:32
#define BLI_INLINE
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP free_value)
Definition: edgehash.c:244
EdgeHash * BLI_edgehash_new_ex(const char *info, const unsigned int nentries_reserve)
Definition: edgehash.c:226
void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val)
Definition: edgehash.c:279
bool BLI_edgeset_add(EdgeSet *es, unsigned int v0, unsigned int v1)
Definition: edgehash.c:578
void BLI_edgeset_free(EdgeSet *es)
Definition: edgehash.c:529
#define BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly)
Definition: BLI_edgehash.h:115
void * BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:325
EdgeSet * BLI_edgeset_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:512
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
MINLINE void normal_float_to_short_v3(short r[3], const float n[3])
MINLINE void normal_short_to_float_v3(float r[3], const short n[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
void range_vn_i(int *array_tar, const int size, const int start)
Definition: math_vector.c:1172
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:109
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Definition: BLI_memarena.c:131
struct MemArena * BLI_memarena_new(const size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:79
unsigned int uint
Definition: BLI_sys_types.h:83
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:231
void BLI_rw_mutex_end(ThreadRWMutex *mutex)
Definition: threads.cc:531
void BLI_mutex_end(ThreadMutex *mutex)
Definition: threads.cc:416
#define THREAD_LOCK_READ
Definition: BLI_threads.h:121
void BLI_mutex_init(ThreadMutex *mutex)
Definition: threads.cc:396
#define THREAD_LOCK_WRITE
Definition: BLI_threads.h:122
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
Definition: threads.cc:516
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:401
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:406
void BLI_rw_mutex_init(ThreadRWMutex *mutex)
Definition: threads.cc:511
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
Definition: threads.cc:526
#define UNUSED_FUNCTION(x)
#define POINTER_FROM_INT(i)
#define POINTER_AS_UINT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define MAX2(a, b)
#define ELEM(...)
#define POINTER_FROM_UINT(i)
void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter)
Definition: CCGSubSurf.c:1456
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
int ccgSubSurf_getVertNumFaces(CCGVert *v)
Definition: CCGSubSurf.c:1284
CCGFace * ccgSubSurf_getVertFace(CCGVert *v, int index)
Definition: CCGSubSurf.c:1288
int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1520
int ccgFaceIterator_isStopped(CCGFaceIterator *fi)
Definition: CCGSubSurf.c:1491
CCGSubSurf * ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator)
Definition: CCGSubSurf.c:241
int ccgEdgeIterator_isStopped(CCGEdgeIterator *ei)
Definition: CCGSubSurf.c:1478
void * ccgSubSurf_getVertData(CCGSubSurf *ss, CCGVert *v)
Definition: CCGSubSurf.c:1306
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
int ccgSubSurf_getSubdivisionLevels(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1234
CCGVert * ccgSubSurf_getEdgeVert0(CCGEdge *e)
Definition: CCGSubSurf.c:1347
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
CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int normalDataOffset)
Definition: CCGSubSurf.c:426
CCGFace * ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f)
Definition: CCGSubSurf.c:1229
CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r)
Definition: CCGSubSurf.c:553
int ccgSubSurf_getSimpleSubdiv(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1261
int ccgSubSurf_getGridSize(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1249
void * ccgSubSurf_getEdgeDataArray(CCGSubSurf *ss, CCGEdge *e)
Definition: CCGSubSurf.c:1355
float ccgSubSurf_getEdgeCrease(CCGEdge *e)
Definition: CCGSubSurf.c:1370
void * ccgSubSurf_getFaceGridEdgeData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x)
Definition: CCGSubSurf.c:1431
CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle(CCGEdge *e)
Definition: CCGSubSurf.c:1320
void * ccgSubSurf_getFaceCenterData(CCGFace *f)
Definition: CCGSubSurf.c:1423
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
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
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
CCGEdge * ccgEdgeIterator_getCurrent(CCGEdgeIterator *ei)
Definition: CCGSubSurf.c:1474
int ccgSubSurf_getNumEdges(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1212
int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1502
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 ccgVertIterator_isStopped(CCGVertIterator *vi)
Definition: CCGSubSurf.c:1465
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
void * ccgSubSurf_getEdgeUserData(CCGSubSurf *ss, CCGEdge *e)
Definition: CCGSubSurf.c:1332
CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
Definition: CCGSubSurf.c:366
CCGVertHDL ccgSubSurf_getVertVertHandle(CCGVert *v)
Definition: CCGSubSurf.c:1268
void * ccgSubSurf_getFaceGridDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex)
Definition: CCGSubSurf.c:1436
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 * CCGEdgeHDL
Definition: CCGSubSurf.h:25
void * CCGVertHDL
Definition: CCGSubSurf.h:24
@ eCCGError_InvalidValue
Definition: CCGSubSurf.h:64
void * CCGAllocatorHDL
Definition: CCGSubSurf.h:42
@ CD_TESSLOOPNORMAL
@ CD_ORIGINDEX
@ CD_MLOOPUV
@ ME_SIMPLE_SUBSURF
@ ME_HIDE
@ ME_EDGEDRAW
@ ME_SEAM
@ ME_EDGERENDER
@ ME_LOOSEEDGE
@ ME_SHARP
@ ME_SMOOTH
@ eSubsurfModifierFlag_Incremental
@ eSubsurfModifierFlag_DebugIncr
@ eSubsurfModifierFlag_ControlEdges
@ SUBSURF_UV_SMOOTH_NONE
Object is a sort of wrapper for general info.
@ OB_MESH
_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 type
_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_SIZE_OPTIMAL(size)
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE void * atomic_cas_ptr(void **v, void *old, void *_new)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
virtual int getNumEdges() const
Definition: btBox2dShape.h:174
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
Scene scene
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static ulong * next
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
const int faceMap[6][4]
Definition: octree.cpp:2827
params N
#define min(a, b)
Definition: sort.c:51
void(* free)(CCGAllocatorHDL a, void *ptr)
Definition: CCGSubSurf.h:47
void(* release)(CCGAllocatorHDL a)
Definition: CCGSubSurf.h:48
void *(* realloc)(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
Definition: CCGSubSurf.h:46
void *(* alloc)(CCGAllocatorHDL a, int numBytes)
Definition: CCGSubSurf.h:45
struct MeshElemMap * pmap
Definition: BKE_subsurf.h:129
struct CCGFace ** gridFaces
Definition: BKE_subsurf.h:134
struct CCGDerivedMesh::@72 * faceMap
struct DMFlagMat * faceFlags
Definition: BKE_subsurf.h:123
struct CCGVert * vert
Definition: BKE_subsurf.h:108
struct CCGSubSurf * ss
Definition: BKE_subsurf.h:102
struct CCGDerivedMesh::@71 * edgeMap
struct MultiresModifierData * mmd
Definition: BKE_subsurf.h:141
unsigned int numGrid
Definition: BKE_subsurf.h:138
struct EdgeHash * ehash
Definition: BKE_subsurf.h:151
MultiresModifiedFlags modified_flags
Definition: BKE_subsurf.h:148
ThreadMutex loops_cache_lock
Definition: BKE_subsurf.h:153
int * reverseFaceMap
Definition: BKE_subsurf.h:125
unsigned int ** gridHidden
Definition: BKE_subsurf.h:136
DerivedMesh dm
Definition: BKE_subsurf.h:100
struct CCGEdge * edge
Definition: BKE_subsurf.h:113
struct Object * ob
Definition: BKE_subsurf.h:147
struct CCGElem ** gridData
Definition: BKE_subsurf.h:132
struct CCGFace * face
Definition: BKE_subsurf.h:119
short * edgeFlags
Definition: BKE_subsurf.h:122
struct CCGDerivedMesh::@73 multires
struct DMFlagMat * gridFlagMats
Definition: BKE_subsurf.h:135
struct CCGDerivedMesh::@70 * vertMap
ThreadRWMutex origindex_cache_rwlock
Definition: BKE_subsurf.h:154
Definition: BKE_ccg.h:48
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
CCGDerivedMesh * ccgdm
Definition: subsurf_ccg.c:1323
struct DerivedMesh::@15 looptris
int(* getGridSize)(DerivedMesh *dm)
struct MLoop *(* getLoopArray)(DerivedMesh *dm)
void(* getVertNo)(DerivedMesh *dm, int index, float r_no[3])
void *(* getVertDataArray)(DerivedMesh *dm, int type)
DMFlagMat *(* getGridFlagMats)(DerivedMesh *dm)
struct MVert *(* getVertArray)(DerivedMesh *dm)
void(* copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop)
void(* copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge)
int(* getNumVerts)(DerivedMesh *dm)
void(* copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly)
int(* getNumPolys)(DerivedMesh *dm)
void *(* getPolyData)(DerivedMesh *dm, int index, int type)
int(* getNumEdges)(DerivedMesh *dm)
struct CCGElem **(* getGridData)(DerivedMesh *dm)
void *(* getLoopDataArray)(DerivedMesh *dm, int type)
void *(* getEdgeData)(DerivedMesh *dm, int index, int type)
int(* getNumGrids)(DerivedMesh *dm)
void *(* getTessFaceDataArray)(DerivedMesh *dm, int type)
CustomData polyData
int(* getNumTessFaces)(DerivedMesh *dm)
struct MLoopTri * array_wip
void(* copyVertArray)(DerivedMesh *dm, struct MVert *r_vert)
void *(* getTessFaceData)(DerivedMesh *dm, int index, int type)
void *(* getVertData)(DerivedMesh *dm, int index, int type)
void *(* getPolyDataArray)(DerivedMesh *dm, int type)
void(* getVert)(DerivedMesh *dm, int index, struct MVert *r_vert)
unsigned int **(* getGridHidden)(DerivedMesh *dm)
void *(* getEdgeDataArray)(DerivedMesh *dm, int type)
struct MEdge *(* getEdgeArray)(DerivedMesh *dm)
void(* getGridKey)(DerivedMesh *dm, struct CCGKey *key)
CustomData edgeData
void(* copyTessFaceArray)(DerivedMesh *dm, struct MFace *r_face)
void(* getEdge)(DerivedMesh *dm, int index, struct MEdge *r_edge)
const struct MeshElemMap *(* getPolyMap)(struct Object *ob, DerivedMesh *dm)
struct MPoly *(* getPolyArray)(DerivedMesh *dm)
CustomData loopData
void(* recalcLoopTri)(DerivedMesh *dm)
struct MLoopTri * array
void(* getTessFace)(DerivedMesh *dm, int index, struct MFace *r_face)
void(* release)(DerivedMesh *dm)
void(* getVertCo)(DerivedMesh *dm, int index, float r_co[3])
int(* getNumLoops)(DerivedMesh *dm)
int *(* getGridOffset)(DerivedMesh *dm)
FaceVertWeight * weight
Definition: subsurf_ccg.c:490
unsigned int level
unsigned int * hidden
unsigned int v1
unsigned int v2
unsigned int v2
unsigned int v1
unsigned int v4
unsigned int v3
unsigned int poly
unsigned int tri[3]
unsigned int e
unsigned int v
short mat_nr
float uv[4][2]
float co[3]
short no[3]
int totvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
ListBase modifiers
void * data
struct RenderData r
unsigned short loop_of_poly_index
unsigned int poly_index
FaceVertWeightEntry * weight_table
Definition: subsurf_ccg.c:496
static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize)
Definition: subsurf_ccg.c:213
static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float r_co[3])
Definition: subsurf_ccg.c:899
static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, DerivedMesh *dm, bool useSubsurfUv)
Definition: subsurf_ccg.c:1997
static CCGSubSurf * _getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLayers, CCGFlags flags)
Definition: subsurf_ccg.c:116
struct FaceVertWeightEntry FaceVertWeightEntry
static void * arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
Definition: subsurf_ccg.c:88
static void * ccgDM_get_edge_data(DerivedMesh *dm, int index, int type)
Definition: subsurf_ccg.c:1716
float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE]
Definition: subsurf_ccg.c:487
void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly, MVert *mvert, const MDisps *mdisps)
Definition: subsurf_ccg.c:1052
static float * get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
Definition: subsurf_ccg.c:500
static void * ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type)
Definition: subsurf_ccg.c:1612
static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
Definition: subsurf_ccg.c:1914
static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
Definition: subsurf_ccg.c:1284
static CCGElem ** ccgDM_getGridData(DerivedMesh *dm)
Definition: subsurf_ccg.c:1822
static const MeshElemMap * ccgDM_getPolyMap(Object *ob, DerivedMesh *dm)
Definition: subsurf_ccg.c:1860
static void ccgdm_create_grids(DerivedMesh *dm)
Definition: subsurf_ccg.c:1768
static void * ccgDM_get_vert_data(DerivedMesh *dm, int index, int type)
Definition: subsurf_ccg.c:1706
static void copyFinalLoopArray_task_cb(void *__restrict userdata, const int iter, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: subsurf_ccg.c:1331
static void * ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
Definition: subsurf_ccg.c:1528
BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
Definition: subsurf_ccg.c:1135
static void UNUSED_FUNCTION() ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
Definition: subsurf_ccg.c:721
static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly)
Definition: subsurf_ccg.c:1418
static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize)
Definition: subsurf_ccg.c:195
static void free_ss_weights(WeightTable *wtable)
Definition: subsurf_ccg.c:556
static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f)
Definition: subsurf_ccg.c:693
static void * ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type)
Definition: subsurf_ccg.c:1726
static int ccgDM_getNumEdges(DerivedMesh *dm)
Definition: subsurf_ccg.c:780
static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v)
Definition: subsurf_ccg.c:683
void subsurf_copy_grid_paint_mask(DerivedMesh *dm, const MPoly *mpoly, float *paint_mask, const GridPaintMask *grid_paint_mask)
Definition: subsurf_ccg.c:1095
static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
Definition: subsurf_ccg.c:807
static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3])
Definition: subsurf_ccg.c:698
bool subsurf_has_edges(DerivedMesh *dm)
Definition: subsurf_ccg.c:2510
static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e)
Definition: subsurf_ccg.c:688
static void * ccgDM_get_poly_data_layer(DerivedMesh *dm, int type)
Definition: subsurf_ccg.c:1669
static int ccgDM_getNumVerts(DerivedMesh *dm)
Definition: subsurf_ccg.c:773
static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MLoopUV *mloopuv)
Definition: subsurf_ccg.c:278
static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
Definition: subsurf_ccg.c:915
static DMFlagMat * ccgDM_getGridFlagMats(DerivedMesh *dm)
Definition: subsurf_ccg.c:1844
static void * ccgDM_get_poly_data(DerivedMesh *dm, int index, int type)
Definition: subsurf_ccg.c:1736
struct DerivedMesh * subsurf_make_derived_from_derived(struct DerivedMesh *dm, struct SubsurfModifierData *smd, const struct Scene *scene, float(*vertCos)[3], SubsurfFlags flags)
Definition: subsurf_ccg.c:2343
static int ccgDM_getNumGrids(DerivedMesh *dm)
Definition: subsurf_ccg.c:1746
static int * ccgDM_getGridOffset(DerivedMesh *dm)
Definition: subsurf_ccg.c:1830
static int ccgDM_getNumLoops(DerivedMesh *dm)
Definition: subsurf_ccg.c:799
void subsurf_calculate_limit_positions(Mesh *me, float(*r_positions)[3])
Definition: subsurf_ccg.c:2458
static void ccgDM_release(DerivedMesh *dm)
Definition: subsurf_ccg.c:1454
#define SUB_ELEMS_FACE
Definition: subsurf_ccg.c:486
static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts)
Definition: subsurf_ccg.c:258
static void ccgDM_recalcLoopTri(DerivedMesh *dm)
Definition: subsurf_ccg.c:1880
bool subsurf_has_faces(DerivedMesh *dm)
Definition: subsurf_ccg.c:2515
static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, float(*vertexCos)[3], int useFlatSubdiv)
Definition: subsurf_ccg.c:571
static int ccgDM_getGridSize(DerivedMesh *dm)
Definition: subsurf_ccg.c:1762
BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
Definition: subsurf_ccg.c:1207
static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
Definition: subsurf_ccg.c:907
static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr))
Definition: subsurf_ccg.c:97
static void * arena_alloc(CCGAllocatorHDL a, int numBytes)
Definition: subsurf_ccg.c:83
static void arena_release(CCGAllocatorHDL a)
Definition: subsurf_ccg.c:102
static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
Definition: subsurf_ccg.c:1001
static int ccgDM_getNumTessFaces(DerivedMesh *dm)
Definition: subsurf_ccg.c:794
static int ccgDM_getNumPolys(DerivedMesh *dm)
Definition: subsurf_ccg.c:787
static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, float(*vertexCos)[3], int use_flat_subdiv, bool UNUSED(use_subdiv_uvs))
Definition: subsurf_ccg.c:672
static BLI_bitmap ** ccgDM_getGridHidden(DerivedMesh *dm)
Definition: subsurf_ccg.c:1852
static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
Definition: subsurf_ccg.c:398
struct CopyFinalLoopArrayData CopyFinalLoopArrayData
static void * ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
Definition: subsurf_ccg.c:1569
static void create_ccgdm_maps(CCGDerivedMesh *ccgdm, CCGSubSurf *ss)
Definition: subsurf_ccg.c:1959
static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
Definition: subsurf_ccg.c:1374
static CCGDerivedMesh * getCCGDerivedMesh(CCGSubSurf *ss, int drawInteriorEdges, int useSubsurfUv, DerivedMesh *dm)
Definition: subsurf_ccg.c:2290
static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int layer_index)
Definition: subsurf_ccg.c:480
static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
Definition: subsurf_ccg.c:1142
CCGFlags
Definition: subsurf_ccg.c:107
@ CCG_ALLOC_MASK
Definition: subsurf_ccg.c:112
@ CCG_CALC_NORMALS
Definition: subsurf_ccg.c:110
@ CCG_USE_ARENA
Definition: subsurf_ccg.c:109
@ CCG_SIMPLE_SUBDIV
Definition: subsurf_ccg.c:113
@ CCG_USE_AGING
Definition: subsurf_ccg.c:108
static void ccgDM_getGridKey(DerivedMesh *dm, CCGKey *key)
Definition: subsurf_ccg.c:1838
static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
Definition: subsurf_ccg.c:1215
struct WeightTable WeightTable
float max
PointerRNA * ptr
Definition: wm_files.c:3157