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
20 /** \file
21 * \ingroup bke
22 */
23
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
77 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
78 int drawInteriorEdges,
79 int useSubsurfUv,
80 DerivedMesh *dm);
81 ///
82
arena_alloc(CCGAllocatorHDL a,int numBytes)83 static void *arena_alloc(CCGAllocatorHDL a, int numBytes)
84 {
85 return BLI_memarena_alloc(a, numBytes);
86 }
87
arena_realloc(CCGAllocatorHDL a,void * ptr,int newSize,int oldSize)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
arena_free(CCGAllocatorHDL UNUSED (a),void * UNUSED (ptr))97 static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr))
98 {
99 /* do nothing */
100 }
101
arena_release(CCGAllocatorHDL a)102 static void arena_release(CCGAllocatorHDL a)
103 {
104 BLI_memarena_free(a);
105 }
106
107 typedef enum {
108 CCG_USE_AGING = 1,
109 CCG_USE_ARENA = 2,
110 CCG_CALC_NORMALS = 4,
111 /* add an extra four bytes for a mask layer */
112 CCG_ALLOC_MASK = 8,
113 CCG_SIMPLE_SUBDIV = 16,
114 } CCGFlags;
115
_getSubSurf(CCGSubSurf * prevSS,int subdivLevels,int numLayers,CCGFlags flags)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
getEdgeIndex(CCGSubSurf * ss,CCGEdge * e,int x,int edgeSize)195 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize)
196 {
197 CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
198 CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
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
getFaceIndex(CCGSubSurf * ss,CCGFace * f,int S,int x,int y,int edgeSize,int gridSize)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) {
220 CCGVert *v = ccgSubSurf_getFaceVert(f, S);
221 return *((int *)ccgSubSurf_getVertUserData(ss, v));
222 }
223 if (x == gridSize - 1) {
224 CCGVert *v = ccgSubSurf_getFaceVert(f, S);
225 CCGEdge *e = ccgSubSurf_getFaceEdge(f, S);
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) {
234 CCGVert *v = ccgSubSurf_getFaceVert(f, S);
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
get_face_uv_map_vert(UvVertMap * vmap,struct MPoly * mpoly,struct MLoop * ml,int fi,CCGVertHDL * fverts)258 static void get_face_uv_map_vert(
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
ss_sync_from_uv(CCGSubSurf * ss,CCGSubSurf * origss,DerivedMesh * dm,MLoopUV * mloopuv)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
305 ccgSubSurf_initFullSync(ss);
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
392 BKE_mesh_uv_vert_map_free(vmap);
393 ccgSubSurf_processSync(ss);
394
395 return 1;
396 }
397
set_subsurf_legacy_uv(CCGSubSurf * ss,DerivedMesh * dm,DerivedMesh * result,int n)398 static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
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 */
417 uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 2, CCG_USE_ARENA);
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");
432 for (ccgSubSurf_initFaceIterator(uvss, &fi); !ccgFaceIterator_isStopped(&fi);
433 ccgFaceIterator_next(&fi)) {
434 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
435 faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
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);
477 MEM_freeN(faceMap);
478 }
479
set_subsurf_uv(CCGSubSurf * ss,DerivedMesh * dm,DerivedMesh * result,int layer_index)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
487 typedef float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE];
488
489 typedef struct FaceVertWeightEntry {
490 FaceVertWeight *weight;
491 float *w;
492 int valid;
493 } FaceVertWeightEntry;
494
495 typedef struct WeightTable {
496 FaceVertWeightEntry *weight_table;
497 int len;
498 } WeightTable;
499
get_ss_weights(WeightTable * wtable,int gridCuts,int faceLen)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
free_ss_weights(WeightTable * wtable)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
ss_sync_ccg_from_derivedmesh(CCGSubSurf * ss,DerivedMesh * dm,float (* vertexCos)[3],int useFlatSubdiv)571 static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
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
596 ccgSubSurf_initFullSync(ss);
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
621 ccgSubSurf_syncEdge(
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) ==
649 eCCGError_InvalidValue) {
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
665 ccgSubSurf_processSync(ss);
666
667 #ifndef USE_DYNSIZE
668 BLI_array_free(fVerts);
669 #endif
670 }
671
ss_sync_from_derivedmesh(CCGSubSurf * ss,DerivedMesh * dm,float (* vertexCos)[3],int use_flat_subdiv,bool UNUSED (use_subdiv_uvs))672 static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
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
ccgDM_getVertMapIndex(CCGSubSurf * ss,CCGVert * v)683 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v)
684 {
685 return ((int *)ccgSubSurf_getVertUserData(ss, v))[1];
686 }
687
ccgDM_getEdgeMapIndex(CCGSubSurf * ss,CCGEdge * e)688 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e)
689 {
690 return ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1];
691 }
692
ccgDM_getFaceMapIndex(CCGSubSurf * ss,CCGFace * f)693 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f)
694 {
695 return ((int *)ccgSubSurf_getFaceUserData(ss, f))[1];
696 }
697
minmax_v3_v3v3(const float vec[3],float min[3],float max[3])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. */
UNUSED_FUNCTION(ccgDM_getMinMax)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
738 for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
739 ccgVertIterator_next(&vi)) {
740 CCGVert *v = ccgVertIterator_getCurrent(&vi);
741 float *co = ccgSubSurf_getVertData(ss, v);
742
743 minmax_v3_v3v3(co, r_min, r_max);
744 }
745
746 for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei);
747 ccgEdgeIterator_next(&ei)) {
748 CCGEdge *e = ccgEdgeIterator_getCurrent(&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
756 for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
757 ccgFaceIterator_next(&fi)) {
758 CCGFace *f = ccgFaceIterator_getCurrent(&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
ccgDM_getNumVerts(DerivedMesh * dm)773 static int ccgDM_getNumVerts(DerivedMesh *dm)
774 {
775 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
776
777 return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
778 }
779
ccgDM_getNumEdges(DerivedMesh * dm)780 static int ccgDM_getNumEdges(DerivedMesh *dm)
781 {
782 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
783
784 return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
785 }
786
ccgDM_getNumPolys(DerivedMesh * dm)787 static int ccgDM_getNumPolys(DerivedMesh *dm)
788 {
789 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
790
791 return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
792 }
793
ccgDM_getNumTessFaces(DerivedMesh * dm)794 static int ccgDM_getNumTessFaces(DerivedMesh *dm)
795 {
796 return dm->numTessFaceData;
797 }
798
ccgDM_getNumLoops(DerivedMesh * dm)799 static int ccgDM_getNumLoops(DerivedMesh *dm)
800 {
801 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
802
803 /* All subsurf faces are quads */
804 return 4 * ccgSubSurf_getNumFinalFaces(ccgdm->ss);
805 }
806
ccgDM_getFinalVert(DerivedMesh * dm,int vertNum,MVert * mv)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) {
846 vd = ccgSubSurf_getFaceCenterData(f);
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
ccgDM_getFinalVertCo(DerivedMesh * dm,int vertNum,float r_co[3])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
ccgDM_getFinalVertNo(DerivedMesh * dm,int vertNum,float r_no[3])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
ccgDM_getFinalEdge(DerivedMesh * dm,int edgeNum,MEdge * med)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
980 if (!ccgSubSurf_getEdgeNumFaces(e)) {
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
ccgDM_getFinalFace(DerivedMesh * dm,int faceNum,MFace * mf)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. */
subsurf_copy_grid_hidden(DerivedMesh * dm,const MPoly * mpoly,MVert * mvert,const MDisps * mdisps)1052 void subsurf_copy_grid_hidden(DerivedMesh *dm,
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. */
subsurf_copy_grid_paint_mask(DerivedMesh * dm,const MPoly * mpoly,float * paint_mask,const GridPaintMask * grid_paint_mask)1095 void subsurf_copy_grid_paint_mask(DerivedMesh *dm,
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 */
ccgDM_to_MVert(MVert * mv,const CCGKey * key,CCGElem * elem)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
ccgDM_copyFinalVertArray(DerivedMesh * dm,MVert * mvert)1142 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
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
1161 vd = ccgSubSurf_getFaceCenterData(f);
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 */
ccgDM_to_MEdge(MEdge * med,const int v1,const int v2,const short flag)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
ccgDM_copyFinalEdgeArray(DerivedMesh * dm,MEdge * medge)1215 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
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;
1260 int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
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
ccgDM_copyFinalFaceArray(DerivedMesh * dm,MFace * mface)1284 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
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 {
1323 CCGDerivedMesh *ccgdm;
1324 MLoop *mloop;
1325 int grid_size;
1326 int *grid_offset;
1327 int edge_size;
1328 size_t mloop_index;
1329 } CopyFinalLoopArrayData;
1330
copyFinalLoopArray_task_cb(void * __restrict userdata,const int iter,const TaskParallelTLS * __restrict UNUSED (tls))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
ccgDM_copyFinalLoopArray(DerivedMesh * dm,MLoop * mloop)1374 static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
1375 {
1376 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1377 CCGSubSurf *ss = ccgdm->ss;
1378
1379 if (!ccgdm->ehash) {
1380 BLI_mutex_lock(&ccgdm->loops_cache_lock);
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 }
1394 BLI_mutex_unlock(&ccgdm->loops_cache_lock);
1395 }
1396
1397 CopyFinalLoopArrayData data;
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;
1411 BLI_parallel_range_settings_defaults(&settings);
1412 settings.min_iter_per_thread = 1;
1413
1414 BLI_task_parallel_range(
1415 0, ccgSubSurf_getNumFaces(ss), &data, copyFinalLoopArray_task_cb, &settings);
1416 }
1417
ccgDM_copyFinalPolyArray(DerivedMesh * dm,MPoly * mpoly)1418 static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly)
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
ccgDM_release(DerivedMesh * dm)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) {
1468 if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED) {
1469 multires_modifier_update_mdisps(dm, NULL);
1470 }
1471 if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED) {
1472 multires_modifier_update_hidden(dm);
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
1521 BLI_mutex_end(&ccgdm->loops_cache_lock);
1522 BLI_rw_mutex_end(&ccgdm->origindex_cache_rwlock);
1523
1524 MEM_freeN(ccgdm);
1525 }
1526 }
1527
ccgDM_get_vert_data_layer(DerivedMesh * dm,int type)1528 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
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 */
1538 BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_READ);
1539 origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1540 BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
1541 if (origindex) {
1542 return origindex;
1543 }
1544
1545 BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_WRITE);
1546 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
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 }
1561 BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
1562
1563 return origindex;
1564 }
1565
1566 return DM_get_vert_data_layer(dm, type);
1567 }
1568
ccgDM_get_edge_data_layer(DerivedMesh * dm,int type)1569 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
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
1585 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
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
ccgDM_get_tessface_data_layer(DerivedMesh * dm,int type)1612 static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type)
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
1624 DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
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 */
1641 tlnors = DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
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
1653 DM_add_tessface_layer(dm, CD_TESSLOOPNORMAL, CD_CALLOC, NULL);
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
ccgDM_get_poly_data_layer(DerivedMesh * dm,int type)1669 static void *ccgDM_get_poly_data_layer(DerivedMesh *dm, int type)
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
1685 DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
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
ccgDM_get_vert_data(DerivedMesh * dm,int index,int type)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 */
1710 ccgDM_get_vert_data_layer(dm, type);
1711 }
1712
1713 return DM_get_vert_data(dm, index, type);
1714 }
1715
ccgDM_get_edge_data(DerivedMesh * dm,int index,int type)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 */
1720 ccgDM_get_edge_data_layer(dm, type);
1721 }
1722
1723 return DM_get_edge_data(dm, index, type);
1724 }
1725
ccgDM_get_tessface_data(DerivedMesh * dm,int index,int type)1726 static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type)
1727 {
1728 if (ELEM(type, CD_ORIGINDEX, CD_TESSLOOPNORMAL)) {
1729 /* ensure creation of CD_ORIGINDEX/CD_TESSLOOPNORMAL layers */
1730 ccgDM_get_tessface_data_layer(dm, type);
1731 }
1732
1733 return DM_get_tessface_data(dm, index, type);
1734 }
1735
ccgDM_get_poly_data(DerivedMesh * dm,int index,int type)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 */
1740 ccgDM_get_tessface_data_layer(dm, type);
1741 }
1742
1743 return DM_get_poly_data(dm, index, type);
1744 }
1745
ccgDM_getNumGrids(DerivedMesh * dm)1746 static int ccgDM_getNumGrids(DerivedMesh *dm)
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
ccgDM_getGridSize(DerivedMesh * dm)1762 static int ccgDM_getGridSize(DerivedMesh *dm)
1763 {
1764 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1765 return ccgSubSurf_getGridSize(ccgdm->ss);
1766 }
1767
ccgdm_create_grids(DerivedMesh * dm)1768 static void ccgdm_create_grids(DerivedMesh *dm)
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
ccgDM_getGridData(DerivedMesh * dm)1822 static CCGElem **ccgDM_getGridData(DerivedMesh *dm)
1823 {
1824 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1825
1826 ccgdm_create_grids(dm);
1827 return ccgdm->gridData;
1828 }
1829
ccgDM_getGridOffset(DerivedMesh * dm)1830 static int *ccgDM_getGridOffset(DerivedMesh *dm)
1831 {
1832 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1833
1834 ccgdm_create_grids(dm);
1835 return ccgdm->gridOffset;
1836 }
1837
ccgDM_getGridKey(DerivedMesh * dm,CCGKey * key)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
ccgDM_getGridFlagMats(DerivedMesh * dm)1844 static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm)
1845 {
1846 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1847
1848 ccgdm_create_grids(dm);
1849 return ccgdm->gridFlagMats;
1850 }
1851
ccgDM_getGridHidden(DerivedMesh * dm)1852 static BLI_bitmap **ccgDM_getGridHidden(DerivedMesh *dm)
1853 {
1854 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1855
1856 ccgdm_create_grids(dm);
1857 return ccgdm->gridHidden;
1858 }
1859
ccgDM_getPolyMap(Object * ob,DerivedMesh * dm)1860 static const MeshElemMap *ccgDM_getPolyMap(Object *ob, DerivedMesh *dm)
1861 {
1862 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1863
1864 if (!ccgdm->multires.mmd && !ccgdm->pmap && ob->type == OB_MESH) {
1865 Mesh *me = ob->data;
1866
1867 BKE_mesh_vert_poly_map_create(&ccgdm->pmap,
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! */
ccgDM_recalcLoopTri(DerivedMesh * dm)1880 static void ccgDM_recalcLoopTri(DerivedMesh *dm)
1881 {
1882 MLoopTri *mlooptri = dm->looptris.array;
1883 const int tottri = dm->numPolyData * 2;
1884 int i, poly_index;
1885
1886 DM_ensure_looptri_data(dm);
1887 mlooptri = dm->looptris.array_wip;
1888
1889 BLI_assert(tottri == 0 || mlooptri != NULL);
1890 BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
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
set_default_ccgdm_callbacks(CCGDerivedMesh * ccgdm)1914 static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
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;
1922 ccgdm->dm.getNumTessFaces = ccgDM_getNumTessFaces;
1923
1924 ccgdm->dm.getVert = ccgDM_getFinalVert;
1925 ccgdm->dm.getEdge = ccgDM_getFinalEdge;
1926 ccgdm->dm.getTessFace = ccgDM_getFinalFace;
1927
1928 ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
1929 ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
1930
1931 ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
1932 ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
1933 ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
1934 ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
1935 ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
1936
1937 ccgdm->dm.getVertData = ccgDM_get_vert_data;
1938 ccgdm->dm.getEdgeData = ccgDM_get_edge_data;
1939 ccgdm->dm.getTessFaceData = ccgDM_get_tessface_data;
1940 ccgdm->dm.getPolyData = ccgDM_get_poly_data;
1941 ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
1942 ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
1943 ccgdm->dm.getTessFaceDataArray = ccgDM_get_tessface_data_layer;
1944 ccgdm->dm.getPolyDataArray = ccgDM_get_poly_data_layer;
1945 ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
1946 ccgdm->dm.getGridSize = ccgDM_getGridSize;
1947 ccgdm->dm.getGridData = ccgDM_getGridData;
1948 ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
1949 ccgdm->dm.getGridKey = ccgDM_getGridKey;
1950 ccgdm->dm.getGridFlagMats = ccgDM_getGridFlagMats;
1951 ccgdm->dm.getGridHidden = ccgDM_getGridHidden;
1952 ccgdm->dm.getPolyMap = ccgDM_getPolyMap;
1953
1954 ccgdm->dm.recalcLoopTri = ccgDM_recalcLoopTri;
1955
1956 ccgdm->dm.release = ccgDM_release;
1957 }
1958
create_ccgdm_maps(CCGDerivedMesh * ccgdm,CCGSubSurf * ss)1959 static void create_ccgdm_maps(CCGDerivedMesh *ccgdm, CCGSubSurf *ss)
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");
1968 for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
1969 ccgVertIterator_next(&vi)) {
1970 CCGVert *v = ccgVertIterator_getCurrent(&vi);
1971
1972 ccgdm->vertMap[POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v))].vert = v;
1973 }
1974
1975 totedge = ccgSubSurf_getNumEdges(ss);
1976 ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
1977 for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei);
1978 ccgEdgeIterator_next(&ei)) {
1979 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
1980
1981 ccgdm->edgeMap[POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
1982 }
1983
1984 totface = ccgSubSurf_getNumFaces(ss);
1985 ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
1986 for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
1987 ccgFaceIterator_next(&fi)) {
1988 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
1989
1990 ccgdm->faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))].face = f;
1991 }
1992 }
1993
1994 /* Fill in all geometry arrays making it possible to access any
1995 * hires data from the CPU.
1996 */
set_ccgdm_all_geometry(CCGDerivedMesh * ccgdm,CCGSubSurf * ss,DerivedMesh * dm,bool useSubsurfUv)1997 static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
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);
2090 vertidx[s] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
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;
2146 CustomData_interp(
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;
2151 CustomData_interp(
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;
2156 CustomData_interp(
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;
2161 CustomData_interp(
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];
2200 int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
2201
2202 CCGVert *v;
2203 v = ccgSubSurf_getEdgeVert0(e);
2204 vertIdx[0] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
2205 v = ccgSubSurf_getEdgeVert1(e);
2206 vertIdx[1] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(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
2262 vertIdx = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
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
getCCGDerivedMesh(CCGSubSurf * ss,int drawInteriorEdges,int useSubsurfUv,DerivedMesh * dm)2290 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
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,
2304 ccgSubSurf_getNumFinalVerts(ss),
2305 ccgSubSurf_getNumFinalEdges(ss),
2306 0,
2307 ccgSubSurf_getNumFinalFaces(ss) * 4,
2308 ccgSubSurf_getNumFinalFaces(ss));
2309
2310 CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL, ccgdm->dm.numPolyData);
2311
2312 ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
2313 "reverseFaceMap");
2314
2315 create_ccgdm_maps(ccgdm, ss);
2316
2317 set_default_ccgdm_callbacks(ccgdm);
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
2329 ccgdm->dm.numVertData = ccgSubSurf_getNumFinalVerts(ss);
2330 ccgdm->dm.numEdgeData = ccgSubSurf_getNumFinalEdges(ss);
2331 ccgdm->dm.numPolyData = ccgSubSurf_getNumFinalFaces(ss);
2332 ccgdm->dm.numLoopData = ccgdm->dm.numPolyData * 4;
2333 ccgdm->dm.numTessFaceData = 0;
2334
2335 BLI_mutex_init(&ccgdm->loops_cache_lock);
2336 BLI_rw_mutex_init(&ccgdm->origindex_cache_rwlock);
2337
2338 return ccgdm;
2339 }
2340
2341 /***/
2342
subsurf_make_derived_from_derived(struct DerivedMesh * dm,struct SubsurfModifierData * smd,const struct Scene * scene,float (* vertCos)[3],SubsurfFlags flags)2343 struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
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);
2354 CCGDerivedMesh *result;
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
subsurf_calculate_limit_positions(Mesh * me,float (* r_positions)[3])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
2472 for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
2473 ccgVertIterator_next(&vi)) {
2474 CCGVert *v = ccgVertIterator_getCurrent(&vi);
2475 int idx = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
2476 int N = ccgSubSurf_getVertNumEdges(v);
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++) {
2485 CCGEdge *e = ccgSubSurf_getVertEdge(v, 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);
2490 add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
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
subsurf_has_edges(DerivedMesh * dm)2510 bool subsurf_has_edges(DerivedMesh *dm)
2511 {
2512 return dm->getNumEdges(dm) != 0;
2513 }
2514
subsurf_has_faces(DerivedMesh * dm)2515 bool subsurf_has_faces(DerivedMesh *dm)
2516 {
2517 return dm->getNumPolys(dm) != 0;
2518 }
2519