LEFT | RIGHT |
1 /* | 1 /* |
2 * ***** BEGIN GPL LICENSE BLOCK ***** | 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
3 * | 3 * |
4 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
6 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
7 * of the License, or (at your option) any later version. | 7 * of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 #include "DNA_scene_types.h" | 45 #include "DNA_scene_types.h" |
46 | 46 |
47 #include "BLI_utildefines.h" | 47 #include "BLI_utildefines.h" |
48 #include "BLI_bitmap.h" | 48 #include "BLI_bitmap.h" |
49 #include "BLI_blenlib.h" | 49 #include "BLI_blenlib.h" |
50 #include "BLI_edgehash.h" | 50 #include "BLI_edgehash.h" |
51 #include "BLI_math.h" | 51 #include "BLI_math.h" |
52 #include "BLI_memarena.h" | 52 #include "BLI_memarena.h" |
53 #include "BLI_pbvh.h" | 53 #include "BLI_pbvh.h" |
54 | 54 |
55 #include "BKE_ccg.h" | |
56 #include "BKE_cdderivedmesh.h" | 55 #include "BKE_cdderivedmesh.h" |
57 #include "BKE_global.h" | 56 #include "BKE_global.h" |
58 #include "BKE_mesh.h" | 57 #include "BKE_mesh.h" |
59 #include "BKE_modifier.h" | |
60 #include "BKE_multires.h" | |
61 #include "BKE_paint.h" | |
62 #include "BKE_scene.h" | |
63 #include "BKE_subsurf.h" | |
64 #include "BKE_tessmesh.h" | |
65 | |
66 #include "PIL_time.h" | |
67 #include "BLI_array.h" | |
68 | |
69 #include "GL/glew.h" | |
70 | |
71 #include "GPU_draw.h" | |
72 #include "GPU_extensions.h" | |
73 #include "GPU_material.h" | |
74 | |
75 #include "CCGSubSurf.h" | |
76 | |
77 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */ | |
78 | |
79 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, | |
80 int drawInteriorEdges, | |
81 int useSubsurfUv, | |
82 DerivedMesh *dm); | |
83 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm); | |
84 | |
85 /// | |
86 | |
87 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) | |
88 { | |
89 return BLI_memarena_alloc(a, numBytes); | |
90 } | |
91 | |
92 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSiz
e) | |
93 { | |
94 void *p2 = BLI_memarena_alloc(a, newSize); | |
95 if (ptr) { | |
96 memcpy(p2, ptr, oldSize); | |
97 } | |
98 return p2; | |
99 } | |
100 | |
101 static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr)) | |
102 { | |
103 /* do nothing */ | |
104 } | |
105 | |
106 static void arena_release(CCGAllocatorHDL a) | |
107 { | |
108 BLI_memarena_free(a); | |
109 } | |
110 | |
111 typedef enum { | |
112 CCG_USE_AGING = 1, | |
113 CCG_USE_ARENA = 2, | |
114 CCG_CALC_NORMALS = 4, | |
115 /* add an extra four bytes for a mask layer */ | |
116 CCG_ALLOC_MASK = 8 | |
117 } CCGFlags; | |
118 | |
119 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, | |
120 int numLayers, CCGFla
gs flags) | |
121 { | |
122 CCGMeshIFC ifc; | |
123 CCGSubSurf *ccgSS; | |
124 int useAging = !!(flags & CCG_USE_AGING); | |
125 int useArena = flags & CCG_USE_ARENA; | |
126 int normalOffset = 0; | |
127 | |
128 /* subdivLevels==0 is not allowed */ | |
129 subdivLevels = MAX2(subdivLevels, 1); | |
130 | |
131 if (prevSS) { | |
132 int oldUseAging; | |
133 | |
134 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NUL
L); | |
135 | |
136 if (oldUseAging != useAging) { | |
137 ccgSubSurf_free(prevSS); | |
138 } | |
139 else { | |
140 ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels); | |
141 | |
142 return prevSS; | |
143 } | |
144 } | |
145 | |
146 if (useAging) { | |
147 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12; | |
148 } | |
149 else { | |
150 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8; | |
151 } | |
152 ifc.numLayers = numLayers; | |
153 ifc.vertDataSize = sizeof(float) * numLayers; | |
154 normalOffset += sizeof(float) * numLayers; | |
155 if(flags & CCG_CALC_NORMALS) | |
156 ifc.vertDataSize += sizeof(float) * 3; | |
157 if(flags & CCG_ALLOC_MASK) | |
158 ifc.vertDataSize += sizeof(float); | |
159 | |
160 if (useArena) { | |
161 CCGAllocatorIFC allocatorIFC; | |
162 CCGAllocatorHDL allocator = BLI_memarena_new((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, alloca
tor); | |
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 else | |
188 ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0); | |
189 | |
190 return ccgSS; | |
191 } | |
192 | |
193 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) | |
194 { | |
195 CCGVert *v0 = ccgSubSurf_getEdgeVert0(e); | |
196 CCGVert *v1 = ccgSubSurf_getEdgeVert1(e); | |
197 int v0idx = *((int *) ccgSubSurf_getVertUserData(ss, v0)); | |
198 int v1idx = *((int *) ccgSubSurf_getVertUserData(ss, v1)); | |
199 int edgeBase = *((int *) ccgSubSurf_getEdgeUserData(ss, e)); | |
200 | |
201 if (x == 0) { | |
202 return v0idx; | |
203 } | |
204 else if (x == edgeSize - 1) { | |
205 return v1idx; | |
206 } | |
207 else { | |
208 return edgeBase + x - 1; | |
209 } | |
210 } | |
211 | |
212 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edg
eSize, int gridSize) | |
213 { | |
214 int faceBase = *((int *) ccgSubSurf_getFaceUserData(ss, f)); | |
215 int numVerts = ccgSubSurf_getFaceNumVerts(f); | |
216 | |
217 if (x == gridSize - 1 && y == gridSize - 1) { | |
218 CCGVert *v = ccgSubSurf_getFaceVert(f, S); | |
219 return *((int *) ccgSubSurf_getVertUserData(ss, v)); | |
220 } | |
221 else if (x == gridSize - 1) { | |
222 CCGVert *v = ccgSubSurf_getFaceVert(f, S); | |
223 CCGEdge *e = ccgSubSurf_getFaceEdge(f, S); | |
224 int edgeBase = *((int *) ccgSubSurf_getEdgeUserData(ss, e)); | |
225 if (v == ccgSubSurf_getEdgeVert0(e)) { | |
226 return edgeBase + (gridSize - 1 - y) - 1; | |
227 } | |
228 else { | |
229 return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 -
y) - 1); | |
230 } | |
231 } | |
232 else if (y == gridSize - 1) { | |
233 CCGVert *v = ccgSubSurf_getFaceVert(f, S); | |
234 CCGEdge *e = ccgSubSurf_getFaceEdge(f, (S + numVerts - 1) % numV
erts); | |
235 int edgeBase = *((int *) ccgSubSurf_getEdgeUserData(ss, e)); | |
236 if (v == ccgSubSurf_getEdgeVert0(e)) { | |
237 return edgeBase + (gridSize - 1 - x) - 1; | |
238 } | |
239 else { | |
240 return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 -
x) - 1); | |
241 } | |
242 } | |
243 else if (x == 0 && y == 0) { | |
244 return faceBase; | |
245 } | |
246 else if (x == 0) { | |
247 S = (S + numVerts - 1) % numVerts; | |
248 return faceBase + 1 + (gridSize - 2) * S + (y - 1); | |
249 } | |
250 else if (y == 0) { | |
251 return faceBase + 1 + (gridSize - 2) * S + (x - 1); | |
252 } | |
253 else { | |
254 return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize
- 2) * (gridSize - 2) + (y - 1) * (gridSize - 2) + (x - 1); | |
255 } | |
256 } | |
257 | |
258 static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mpoly, struct ML
oop *ml, int fi, CCGVertHDL *fverts) | |
259 { | |
260 UvMapVert *v, *nv; | |
261 int j, nverts = mpoly[fi].totloop; | |
262 | |
263 for (j = 0; j < nverts; j++) { | |
264 for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v
= v->next) { | |
265 if (v->separate) | |
266 nv = v; | |
267 if (v->f == fi) | |
268 break; | |
269 } | |
270 | |
271 fverts[j] = SET_INT_IN_POINTER(mpoly[nv->f].loopstart + nv->tfin
dex); | |
272 } | |
273 } | |
274 | |
275 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
MLoopUV *mloopuv) | |
276 { | |
277 MPoly *mpoly = dm->getPolyArray(dm); | |
278 MLoop *mloop = dm->getLoopArray(dm); | |
279 MVert *mvert = dm->getVertArray(dm); | |
280 int totvert = dm->getNumVerts(dm); | |
281 int totface = dm->getNumPolys(dm); | |
282 int i, j, seam; | |
283 UvMapVert *v; | |
284 UvVertMap *vmap; | |
285 float limit[2]; | |
286 CCGVertHDL *fverts = NULL; | |
287 BLI_array_declare(fverts); | |
288 EdgeHash *ehash; | |
289 float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss); | |
290 float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written int
o */ | |
291 | |
292 limit[0] = limit[1] = STD_UV_CONNECT_LIMIT; | |
293 vmap = BKE_mesh_uv_vert_map_make(mpoly, mloop, mloopuv, totface, totvert
, 0, limit); | |
294 if (!vmap) | |
295 return 0; | |
296 ········ | |
297 ccgSubSurf_initFullSync(ss); | |
298 | |
299 /* create vertices */ | |
300 for (i = 0; i < totvert; i++) { | |
301 if (!BKE_mesh_uv_vert_map_get_vert(vmap, i)) | |
302 continue; | |
303 | |
304 for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i)->next; v; v = v-
>next) | |
305 if (v->separate) | |
306 break; | |
307 | |
308 seam = (v != NULL) || ((mvert + i)->flag & ME_VERT_MERGED); | |
309 | |
310 for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next)
{ | |
311 if (v->separate) { | |
312 CCGVert *ssv; | |
313 int loopid = mpoly[v->f].loopstart + v->tfindex; | |
314 CCGVertHDL vhdl = SET_INT_IN_POINTER(loopid); | |
315 | |
316 copy_v2_v2(uv, mloopuv[loopid].uv); | |
317 | |
318 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv); | |
319 } | |
320 } | |
321 } | |
322 | |
323 /* create edges */ | |
324 ehash = BLI_edgehash_new(); | |
325 | |
326 for (i = 0; i < totface; i++) { | |
327 MPoly *mp = &((MPoly *) mpoly)[i]; | |
328 int nverts = mp->totloop; | |
329 CCGFace *origf = ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i
)); | |
330 /* unsigned int *fv = &mp->v1; */ | |
331 MLoop *ml = mloop + mp->loopstart; | |
332 | |
333 BLI_array_empty(fverts); | |
334 BLI_array_grow_items(fverts, nverts); | |
335 | |
336 get_face_uv_map_vert(vmap, mpoly, ml, i, fverts); | |
337 | |
338 for (j = 0; j < nverts; j++) { | |
339 int v0 = GET_INT_FROM_POINTER(fverts[j]); | |
340 int v1 = GET_INT_FROM_POINTER(fverts[(j + 1) % nverts]); | |
341 MVert *mv0 = mvert + (ml[j].v); | |
342 MVert *mv1 = mvert + (ml[((j + 1) % nverts)].v); | |
343 | |
344 if (!BLI_edgehash_haskey(ehash, v0, v1)) { | |
345 CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(orig
f, j); | |
346 CCGEdgeHDL ehdl = SET_INT_IN_POINTER(mp->loopsta
rt + j); | |
347 float crease; | |
348 | |
349 if ((mv0->flag & mv1->flag) & ME_VERT_MERGED) | |
350 crease = creaseFactor; | |
351 else | |
352 crease = ccgSubSurf_getEdgeCrease(orige)
; | |
353 | |
354 ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[
(j + 1) % nverts], crease, &e); | |
355 BLI_edgehash_insert(ehash, v0, v1, NULL); | |
356 } | |
357 } | |
358 } | |
359 | |
360 BLI_edgehash_free(ehash, NULL); | |
361 | |
362 /* create faces */ | |
363 for (i = 0; i < totface; i++) { | |
364 MPoly *mp = &mpoly[i]; | |
365 MLoop *ml = &mloop[mp->loopstart]; | |
366 int nverts = mp->totloop; | |
367 CCGFace *f; | |
368 | |
369 BLI_array_empty(fverts); | |
370 BLI_array_grow_items(fverts, nverts); | |
371 | |
372 get_face_uv_map_vert(vmap, mpoly, ml, i, fverts); | |
373 ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &
f); | |
374 } | |
375 | |
376 BLI_array_free(fverts); | |
377 | |
378 BKE_mesh_uv_vert_map_free(vmap); | |
379 ccgSubSurf_processSync(ss); | |
380 | |
381 return 1; | |
382 } | |
383 | |
384 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
int n) | |
385 { | |
386 CCGSubSurf *uvss; | |
387 CCGFace **faceMap; | |
388 MTFace *tf; | |
389 MLoopUV *mluv; | |
390 CCGFaceIterator *fi; | |
391 int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S; | |
392 MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n)
; | |
393 /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away w
ith | |
394 * just tface except applying the modifier then looses subsurf UV */ | |
395 MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n); | |
396 MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV,
n); | |
397 | |
398 if (!dmloopuv || (!tface && !mloopuv)) | |
399 return; | |
400 | |
401 /* create a CCGSubSurf from uv's */ | |
402 uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 2, CCG_USE
_ARENA); | |
403 | |
404 if (!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) { | |
405 ccgSubSurf_free(uvss); | |
406 return; | |
407 } | |
408 | |
409 /* get some info from CCGSubSurf */ | |
410 totface = ccgSubSurf_getNumFaces(uvss); | |
411 /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/ | |
412 gridSize = ccgSubSurf_getGridSize(uvss); | |
413 gridFaces = gridSize - 1; | |
414 | |
415 /* make a map from original faces to CCGFaces */ | |
416 faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv"); | |
417 | |
418 fi = ccgSubSurf_getFaceIterator(uvss); | |
419 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { | |
420 CCGFace *f = ccgFaceIterator_getCurrent(fi); | |
421 faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] =
f; | |
422 } | |
423 ccgFaceIterator_free(fi); | |
424 | |
425 /* load coordinates from uvss into tface */ | |
426 tf = tface; | |
427 mluv = mloopuv; | |
428 | |
429 for (index = 0; index < totface; index++) { | |
430 CCGFace *f = faceMap[index]; | |
431 int numVerts = ccgSubSurf_getFaceNumVerts(f); | |
432 | |
433 for (S = 0; S < numVerts; S++) { | |
434 float (*faceGridData)[2] = ccgSubSurf_getFaceGridDataArr
ay(uvss, f, S); | |
435 | |
436 for (y = 0; y < gridFaces; y++) { | |
437 for (x = 0; x < gridFaces; x++) { | |
438 float *a = faceGridData[(y + 0) * gridSi
ze + x + 0]; | |
439 float *b = faceGridData[(y + 0) * gridSi
ze + x + 1]; | |
440 float *c = faceGridData[(y + 1) * gridSi
ze + x + 1]; | |
441 float *d = faceGridData[(y + 1) * gridSi
ze + x + 0]; | |
442 | |
443 if (tf) { | |
444 copy_v2_v2(tf->uv[0], a); | |
445 copy_v2_v2(tf->uv[1], d); | |
446 copy_v2_v2(tf->uv[2], c); | |
447 copy_v2_v2(tf->uv[3], b); | |
448 tf++; | |
449 } | |
450 | |
451 if (mluv) { | |
452 copy_v2_v2(mluv[0].uv, a); | |
453 copy_v2_v2(mluv[1].uv, d); | |
454 copy_v2_v2(mluv[2].uv, c); | |
455 copy_v2_v2(mluv[3].uv, b); | |
456 mluv += 4; | |
457 } | |
458 | |
459 } | |
460 } | |
461 } | |
462 } | |
463 | |
464 ccgSubSurf_free(uvss); | |
465 MEM_freeN(faceMap); | |
466 } | |
467 | |
468 /* face weighting */ | |
469 typedef struct FaceVertWeightEntry { | |
470 FaceVertWeight *weight; | |
471 float *w; | |
472 int valid; | |
473 } FaceVertWeightEntry; | |
474 | |
475 typedef struct WeightTable { | |
476 FaceVertWeightEntry *weight_table; | |
477 int len; | |
478 } WeightTable; | |
479 | |
480 static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen) | |
481 { | |
482 int x, y, i, j; | |
483 float *w, w1, w2, w4, fac, fac2, fx, fy; | |
484 | |
485 if (wtable->len <= faceLen) { | |
486 void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry) * (faceLen +
1), "weight table alloc 2"); | |
487 ················ | |
488 if (wtable->len) { | |
489 memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightE
ntry) * wtable->len); | |
490 MEM_freeN(wtable->weight_table); | |
491 } | |
492 ················ | |
493 wtable->weight_table = tmp; | |
494 wtable->len = faceLen + 1; | |
495 } | |
496 | |
497 if (!wtable->weight_table[faceLen].valid) { | |
498 wtable->weight_table[faceLen].valid = 1; | |
499 wtable->weight_table[faceLen].w = w = MEM_callocN(sizeof(float)
* faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), "weight table alloc"); | |
500 fac = 1.0f / (float)faceLen; | |
501 | |
502 for (i = 0; i < faceLen; i++) { | |
503 for (x = 0; x < gridCuts + 2; x++) { | |
504 for (y = 0; y < gridCuts + 2; y++) { | |
505 fx = 0.5f - (float)x / (float)(gridCuts
+ 1) / 2.0f; | |
506 fy = 0.5f - (float)y / (float)(gridCuts
+ 1) / 2.0f; | |
507 ································ | |
508 fac2 = faceLen - 4; | |
509 w1 = (1.0f - fx) * (1.0f - fy) + (-fac2
* fx * fy * fac); | |
510 w2 = (1.0f - fx + fac2 * fx * -fac) * (f
y); | |
511 w4 = (fx) * (1.0f - fy + -fac2 * fy * fa
c); | |
512 | |
513 fac2 = 1.0f - (w1 + w2 + w4); | |
514 fac2 = fac2 / (float)(faceLen - 3); | |
515 for (j = 0; j < faceLen; j++) | |
516 w[j] = fac2; | |
517 ········································ | |
518 w[i] = w1; | |
519 w[(i - 1 + faceLen) % faceLen] = w2; | |
520 w[(i + 1) % faceLen] = w4; | |
521 | |
522 w += faceLen; | |
523 } | |
524 } | |
525 } | |
526 } | |
527 | |
528 return wtable->weight_table[faceLen].w; | |
529 } | |
530 | |
531 static void free_ss_weights(WeightTable *wtable) | |
532 { | |
533 int i; | |
534 | |
535 for (i = 0; i < wtable->len; i++) { | |
536 if (wtable->weight_table[i].valid) | |
537 MEM_freeN(wtable->weight_table[i].w); | |
538 } | |
539 ········ | |
540 if (wtable->weight_table) | |
541 MEM_freeN(wtable->weight_table); | |
542 } | |
543 | |
544 static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, | |
545 float (*vertexCos)[3], int useFlatSubdiv) | |
546 { | |
547 float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss); | |
548 CCGVertHDL *fVerts = NULL; | |
549 BLI_array_declare(fVerts); | |
550 MVert *mvert = dm->getVertArray(dm); | |
551 MEdge *medge = dm->getEdgeArray(dm); | |
552 /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */ | |
553 MVert *mv; | |
554 MEdge *me; | |
555 MLoop *mloop = dm->getLoopArray(dm), *ml; | |
556 MPoly *mpoly = dm->getPolyArray(dm), *mp; | |
557 /*MFace *mf;*/ /*UNUSED*/ | |
558 int totvert = dm->getNumVerts(dm); | |
559 int totedge = dm->getNumEdges(dm); | |
560 /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/ | |
561 /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/ | |
562 int i, j; | |
563 int *index; | |
564 | |
565 ccgSubSurf_initFullSync(ss); | |
566 | |
567 mv = mvert; | |
568 index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX); | |
569 for (i = 0; i < totvert; i++, mv++) { | |
570 CCGVert *v; | |
571 | |
572 if (vertexCos) { | |
573 ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos
[i], 0, &v); | |
574 } | |
575 else { | |
576 ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0
, &v); | |
577 } | |
578 | |
579 ((int *)ccgSubSurf_getVertUserData(ss, v))[1] = (index) ? *index
++ : i; | |
580 } | |
581 | |
582 me = medge; | |
583 index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX); | |
584 for (i = 0; i < totedge; i++, me++) { | |
585 CCGEdge *e; | |
586 float crease; | |
587 | |
588 crease = useFlatSubdiv ? creaseFactor : | |
589 me->crease * creaseFactor / 255.0f; | |
590 | |
591 ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTE
R(me->v1), | |
592 SET_INT_IN_POINTER(me->v2), crease, &e); | |
593 | |
594 ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index) ? *index
++ : i; | |
595 } | |
596 | |
597 mp = mpoly; | |
598 index = DM_get_poly_data_layer(dm, CD_ORIGINDEX); | |
599 for (i = 0; i < dm->numPolyData; i++, mp++) { | |
600 CCGFace *f; | |
601 | |
602 BLI_array_empty(fVerts); | |
603 BLI_array_grow_items(fVerts, mp->totloop); | |
604 | |
605 ml = mloop + mp->loopstart; | |
606 for (j = 0; j < mp->totloop; j++, ml++) { | |
607 fVerts[j] = SET_INT_IN_POINTER(ml->v); | |
608 } | |
609 | |
610 /* this is very bad, means mesh is internally inconsistent. | |
611 * it is not really possible to continue without modifying | |
612 * other parts of code significantly to handle missing faces. | |
613 * since this really shouldn't even be possible we just bail.*/ | |
614 if (ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), mp->totloop, | |
615 fVerts, &f) == eCCGError_InvalidValue) { | |
616 static int hasGivenError = 0; | |
617 | |
618 if (!hasGivenError) { | |
619 //XXX error("Unrecoverable error in SubSurf calc
ulation," | |
620 // " mesh is inconsistent."); | |
621 | |
622 hasGivenError = 1; | |
623 } | |
624 | |
625 return; | |
626 } | |
627 | |
628 ((int *)ccgSubSurf_getFaceUserData(ss, f))[1] = (index) ? *index
++ : i; | |
629 } | |
630 | |
631 ccgSubSurf_processSync(ss); | |
632 | |
633 BLI_array_free(fVerts); | |
634 } | |
635 | |
636 /***/ | |
637 | |
638 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v) | |
639 { | |
640 return ((int *) ccgSubSurf_getVertUserData(ss, v))[1]; | |
641 } | |
642 | |
643 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e) | |
644 { | |
645 return ((int *) ccgSubSurf_getEdgeUserData(ss, e))[1]; | |
646 } | |
647 | |
648 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) | |
649 { | |
650 return ((int *) ccgSubSurf_getFaceUserData(ss, f))[1]; | |
651 } | |
652 | |
653 static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3]) | |
654 { | |
655 if(min[0] > vec[0]) min[0]= vec[0]; | |
656 if(min[1] > vec[1]) min[1]= vec[1]; | |
657 if(min[2] > vec[2]) min[2]= vec[2]; | |
658 if(max[0] < vec[0]) max[0]= vec[0]; | |
659 if(max[1] < vec[1]) max[1]= vec[1]; | |
660 if(max[2] < vec[2]) max[2]= vec[2]; | |
661 } | |
662 | |
663 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) | |
664 { | |
665 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
666 CCGSubSurf *ss = ccgdm->ss; | |
667 CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss); | |
668 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); | |
669 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); | |
670 CCGKey key; | |
671 int i, edgeSize = ccgSubSurf_getEdgeSize(ss); | |
672 int gridSize = ccgSubSurf_getGridSize(ss); | |
673 | |
674 CCG_key_top_level(&key, ss); | |
675 | |
676 if (!ccgSubSurf_getNumVerts(ss)) | |
677 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2]
= 0.0; | |
678 | |
679 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { | |
680 CCGVert *v = ccgVertIterator_getCurrent(vi); | |
681 float *co = ccgSubSurf_getVertData(ss, v); | |
682 | |
683 minmax_v3_v3v3(co, min_r, max_r); | |
684 } | |
685 | |
686 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { | |
687 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); | |
688 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); | |
689 | |
690 for (i=0; i < edgeSize; i++) | |
691 minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), mi
n_r, max_r); | |
692 } | |
693 | |
694 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { | |
695 CCGFace *f = ccgFaceIterator_getCurrent(fi); | |
696 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
697 | |
698 for (S = 0; S < numVerts; S++) { | |
699 CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(
ss, f, S); | |
700 | |
701 for (y = 0; y < gridSize; y++) | |
702 for (x = 0; x < gridSize; x++) | |
703 minmax_v3_v3v3(CCG_grid_elem_co(&key, fa
ceGridData, x, y), min_r, max_r); | |
704 } | |
705 } | |
706 | |
707 ccgFaceIterator_free(fi); | |
708 ccgEdgeIterator_free(ei); | |
709 ccgVertIterator_free(vi); | |
710 } | |
711 | |
712 static int ccgDM_getNumVerts(DerivedMesh *dm) | |
713 { | |
714 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
715 | |
716 return ccgSubSurf_getNumFinalVerts(ccgdm->ss); | |
717 } | |
718 | |
719 static int ccgDM_getNumEdges(DerivedMesh *dm) | |
720 { | |
721 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
722 | |
723 return ccgSubSurf_getNumFinalEdges(ccgdm->ss); | |
724 } | |
725 | |
726 static int ccgDM_getNumTessFaces(DerivedMesh *dm) | |
727 { | |
728 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
729 | |
730 return ccgSubSurf_getNumFinalFaces(ccgdm->ss); | |
731 } | |
732 | |
733 static int ccgDM_getNumLoops(DerivedMesh *dm) | |
734 { | |
735 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
736 | |
737 /* All subsurf faces are quads */ | |
738 return 4 * ccgSubSurf_getNumFinalFaces(ccgdm->ss); | |
739 } | |
740 | |
741 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) | |
742 { | |
743 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
744 CCGSubSurf *ss = ccgdm->ss; | |
745 CCGElem *vd; | |
746 CCGKey key; | |
747 int i; | |
748 | |
749 CCG_key_top_level(&key, ss); | |
750 memset(mv, 0, sizeof(*mv)); | |
751 | |
752 if ((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(s
s) > 0)) { | |
753 /* this vert comes from face data */ | |
754 int lastface = ccgSubSurf_getNumFaces(ss) - 1; | |
755 CCGFace *f; | |
756 int x, y, grid, numVerts; | |
757 int offset; | |
758 int gridSize = ccgSubSurf_getGridSize(ss); | |
759 int gridSideVerts; | |
760 int gridInternalVerts; | |
761 int gridSideEnd; | |
762 int gridInternalEnd; | |
763 | |
764 i = 0; | |
765 while (i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVer
t) | |
766 ++i; | |
767 | |
768 f = ccgdm->faceMap[i].face; | |
769 numVerts = ccgSubSurf_getFaceNumVerts(f); | |
770 | |
771 gridSideVerts = gridSize - 2; | |
772 gridInternalVerts = gridSideVerts * gridSideVerts; | |
773 | |
774 gridSideEnd = 1 + numVerts * gridSideVerts; | |
775 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts; | |
776 | |
777 offset = vertNum - ccgdm->faceMap[i].startVert; | |
778 if (offset < 1) { | |
779 vd = ccgSubSurf_getFaceCenterData(f); | |
780 copy_v3_v3(mv->co, CCG_elem_co(&key, vd)); | |
781 normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd)); | |
782 } | |
783 else if (offset < gridSideEnd) { | |
784 offset -= 1; | |
785 grid = offset / gridSideVerts; | |
786 x = offset % gridSideVerts + 1; | |
787 vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x); | |
788 copy_v3_v3(mv->co, CCG_elem_co(&key, vd)); | |
789 normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd)); | |
790 } | |
791 else if (offset < gridInternalEnd) { | |
792 offset -= gridSideEnd; | |
793 grid = offset / gridInternalVerts; | |
794 offset %= gridInternalVerts; | |
795 y = offset / gridSideVerts + 1; | |
796 x = offset % gridSideVerts + 1; | |
797 vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y); | |
798 copy_v3_v3(mv->co, CCG_elem_co(&key, vd)); | |
799 normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd)); | |
800 } | |
801 } | |
802 else if ((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEd
ges(ss) > 0)) { | |
803 /* this vert comes from edge data */ | |
804 CCGEdge *e; | |
805 int lastedge = ccgSubSurf_getNumEdges(ss) - 1; | |
806 int x; | |
807 | |
808 i = 0; | |
809 while (i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVer
t) | |
810 ++i; | |
811 | |
812 e = ccgdm->edgeMap[i].edge; | |
813 | |
814 x = vertNum - ccgdm->edgeMap[i].startVert + 1; | |
815 vd = ccgSubSurf_getEdgeData(ss, e, x); | |
816 copy_v3_v3(mv->co, CCG_elem_co(&key, vd)); | |
817 normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd)); | |
818 } | |
819 else { | |
820 /* this vert comes from vert data */ | |
821 CCGVert *v; | |
822 i = vertNum - ccgdm->vertMap[0].startVert; | |
823 | |
824 v = ccgdm->vertMap[i].vert; | |
825 vd = ccgSubSurf_getVertData(ss, v); | |
826 copy_v3_v3(mv->co, CCG_elem_co(&key, vd)); | |
827 normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd)); | |
828 } | |
829 } | |
830 | |
831 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float co_r[3]) | |
832 { | |
833 MVert mvert; | |
834 | |
835 ccgDM_getFinalVert(dm, vertNum, &mvert); | |
836 copy_v3_v3(co_r, mvert.co); | |
837 } | |
838 | |
839 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3]) | |
840 { | |
841 MVert mvert; | |
842 | |
843 ccgDM_getFinalVert(dm, vertNum, &mvert); | |
844 normal_short_to_float_v3(no_r, mvert.no); | |
845 } | |
846 | |
847 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med) | |
848 { | |
849 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
850 CCGSubSurf *ss = ccgdm->ss; | |
851 int i; | |
852 | |
853 memset(med, 0, sizeof(*med)); | |
854 | |
855 if (edgeNum < ccgdm->edgeMap[0].startEdge) { | |
856 /* this edge comes from face data */ | |
857 int lastface = ccgSubSurf_getNumFaces(ss) - 1; | |
858 CCGFace *f; | |
859 int x, y, grid /*, numVerts*/; | |
860 int offset; | |
861 int gridSize = ccgSubSurf_getGridSize(ss); | |
862 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
863 int gridSideEdges; | |
864 int gridInternalEdges; | |
865 | |
866 /* code added in bmesh but works correctly without, commenting -
campbell */ | |
867 #if 0 | |
868 int lasti, previ; | |
869 i = lastface; | |
870 lasti = 0; | |
871 while (1) { | |
872 previ = i; | |
873 if (ccgdm->faceMap[i].startEdge >= edgeNum) { | |
874 i -= fabsf(i - lasti) / 2.0f; | |
875 } | |
876 else if (ccgdm->faceMap[i].startEdge < edgeNum) { | |
877 i += fabsf(i - lasti) / 2.0f; | |
878 } | |
879 else { | |
880 break; | |
881 } | |
882 | |
883 if (i < 0) { | |
884 i = 0; | |
885 break; | |
886 } | |
887 | |
888 if (i > lastface) { | |
889 i = lastface; | |
890 break; | |
891 | |
892 } | |
893 | |
894 if (i == lasti) | |
895 break; | |
896 | |
897 lasti = previ; | |
898 } | |
899 | |
900 i = i > 0 ? i - 1 : i; | |
901 #endif | |
902 | |
903 i = 0; | |
904 while (i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdg
e) | |
905 ++i; | |
906 | |
907 f = ccgdm->faceMap[i].face; | |
908 /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/ | |
909 | |
910 gridSideEdges = gridSize - 1; | |
911 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;· | |
912 | |
913 offset = edgeNum - ccgdm->faceMap[i].startEdge; | |
914 grid = offset / (gridSideEdges + gridInternalEdges); | |
915 offset %= (gridSideEdges + gridInternalEdges); | |
916 | |
917 if (offset < gridSideEdges) { | |
918 x = offset; | |
919 med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, grid
Size); | |
920 med->v2 = getFaceIndex(ss, f, grid, x + 1, 0, edgeSize,
gridSize); | |
921 } | |
922 else { | |
923 offset -= gridSideEdges; | |
924 x = (offset / 2) / gridSideEdges + 1; | |
925 y = (offset / 2) % gridSideEdges; | |
926 if (offset % 2 == 0) { | |
927 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSi
ze, gridSize); | |
928 med->v2 = getFaceIndex(ss, f, grid, x, y + 1, ed
geSize, gridSize); | |
929 } | |
930 else { | |
931 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSi
ze, gridSize); | |
932 med->v2 = getFaceIndex(ss, f, grid, y + 1, x, ed
geSize, gridSize); | |
933 } | |
934 } | |
935 } | |
936 else { | |
937 /* this vert comes from edge data */ | |
938 CCGEdge *e; | |
939 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
940 int x; | |
941 short *edgeFlag; | |
942 unsigned int flags = 0; | |
943 | |
944 i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1); | |
945 | |
946 e = ccgdm->edgeMap[i].edge; | |
947 | |
948 if (!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; | |
949 | |
950 x = edgeNum - ccgdm->edgeMap[i].startEdge; | |
951 | |
952 med->v1 = getEdgeIndex(ss, e, x, edgeSize); | |
953 med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize); | |
954 | |
955 edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL; | |
956 if (edgeFlag) | |
957 flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRA
W | ME_EDGERENDER; | |
958 else | |
959 flags |= ME_EDGEDRAW | ME_EDGERENDER; | |
960 | |
961 med->flag = flags; | |
962 } | |
963 } | |
964 | |
965 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) | |
966 { | |
967 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
968 CCGSubSurf *ss = ccgdm->ss; | |
969 int gridSize = ccgSubSurf_getGridSize(ss); | |
970 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
971 int gridSideEdges = gridSize - 1; | |
972 int gridFaces = gridSideEdges * gridSideEdges; | |
973 int i; | |
974 CCGFace *f; | |
975 /*int numVerts;*/ | |
976 int offset; | |
977 int grid; | |
978 int x, y; | |
979 /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/ | |
980 DMFlagMat *faceFlags = ccgdm->faceFlags; | |
981 | |
982 memset(mf, 0, sizeof(*mf)); | |
983 if (faceNum >= ccgdm->dm.numTessFaceData) | |
984 return; | |
985 | |
986 i = ccgdm->reverseFaceMap[faceNum]; | |
987 | |
988 f = ccgdm->faceMap[i].face; | |
989 /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/ | |
990 | |
991 offset = faceNum - ccgdm->faceMap[i].startFace; | |
992 grid = offset / gridFaces; | |
993 offset %= gridFaces; | |
994 y = offset / gridSideEdges; | |
995 x = offset % gridSideEdges; | |
996 | |
997 mf->v1 = getFaceIndex(ss, f, grid, x + 0, y + 0, edgeSize, gridSize); | |
998 mf->v2 = getFaceIndex(ss, f, grid, x + 0, y + 1, edgeSize, gridSize); | |
999 mf->v3 = getFaceIndex(ss, f, grid, x + 1, y + 1, edgeSize, gridSize); | |
1000 mf->v4 = getFaceIndex(ss, f, grid, x + 1, y + 0, edgeSize, gridSize); | |
1001 | |
1002 if (faceFlags) { | |
1003 mf->flag = faceFlags[i].flag; | |
1004 mf->mat_nr = faceFlags[i].mat_nr; | |
1005 } | |
1006 else mf->flag = ME_SMOOTH; | |
1007 } | |
1008 | |
1009 /* Translate GridHidden into the ME_HIDE flag for MVerts. Assumes | |
1010 * vertices are in the order output by ccgDM_copyFinalVertArray. */ | |
1011 void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly, | |
1012 MVert *mvert, const MDisps *mdisps) | |
1013 { | |
1014 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
1015 CCGSubSurf *ss = ccgdm->ss; | |
1016 int level = ccgSubSurf_getSubdivisionLevels(ss); | |
1017 int gridSize = ccgSubSurf_getGridSize(ss); | |
1018 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1019 int totface = ccgSubSurf_getNumFaces(ss); | |
1020 int i, j, x, y; | |
1021 ········ | |
1022 for (i = 0; i < totface; i++) { | |
1023 CCGFace *f = ccgdm->faceMap[i].face; | |
1024 | |
1025 for (j = 0; j < mpoly[i].totloop; j++) { | |
1026 const MDisps *md = &mdisps[mpoly[i].loopstart + j]; | |
1027 int hidden_gridsize = ccg_gridsize(md->level); | |
1028 int factor = ccg_factor(level, md->level); | |
1029 ························ | |
1030 if (!md->hidden) | |
1031 continue; | |
1032 ························ | |
1033 for (y = 0; y < gridSize; y++) { | |
1034 for (x = 0; x < gridSize; x++) { | |
1035 int vndx, offset; | |
1036 ········································ | |
1037 vndx = getFaceIndex(ss, f, j, x, y, edge
Size, gridSize); | |
1038 offset = (y * factor) * hidden_gridsize
+ (x * factor); | |
1039 if (BLI_BITMAP_GET(md->hidden, offset)) | |
1040 mvert[vndx].flag |= ME_HIDE; | |
1041 } | |
1042 } | |
1043 } | |
1044 } | |
1045 } | |
1046 | |
1047 /* Translate GridPaintMask into vertex paint masks. Assumes vertices | |
1048 are in the order output by ccgDM_copyFinalVertArray. */ | |
1049 void subsurf_copy_grid_paint_mask(DerivedMesh *dm, const MPoly *mpoly, | |
1050 float *paint_m
ask, | |
1051 const GridPain
tMask *grid_paint_mask) | |
1052 { | |
1053 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm; | |
1054 CCGSubSurf *ss = ccgdm->ss; | |
1055 int level = ccgSubSurf_getSubdivisionLevels(ss); | |
1056 int gridSize = ccgSubSurf_getGridSize(ss); | |
1057 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1058 int totface = ccgSubSurf_getNumFaces(ss); | |
1059 int i, j, x, y, factor, gpm_gridsize; | |
1060 ········ | |
1061 for(i = 0; i < totface; i++) { | |
1062 CCGFace *f = ccgdm->faceMap[i].face; | |
1063 const MPoly *p = &mpoly[i]; | |
1064 ················ | |
1065 for(j = 0; j < p->totloop; j++) { | |
1066 const GridPaintMask *gpm = &grid_paint_mask[p->loopstart
+ j]; | |
1067 if(!gpm->data) | |
1068 continue; | |
1069 | |
1070 factor = ccg_factor(level, gpm->level); | |
1071 gpm_gridsize = ccg_gridsize(gpm->level); | |
1072 ························ | |
1073 for(y = 0; y < gridSize; y++) { | |
1074 for(x = 0; x < gridSize; x++) { | |
1075 int vndx, offset; | |
1076 ········································ | |
1077 vndx = getFaceIndex(ss, f, j, x, y, edge
Size, gridSize); | |
1078 offset = y*factor * gpm_gridsize + x*fac
tor; | |
1079 paint_mask[vndx] = gpm->data[offset]; | |
1080 } | |
1081 } | |
1082 } | |
1083 } | |
1084 } | |
1085 | |
1086 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) | |
1087 { | |
1088 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1089 CCGSubSurf *ss = ccgdm->ss; | |
1090 CCGElem *vd; | |
1091 CCGKey key; | |
1092 int index; | |
1093 int totvert, totedge, totface; | |
1094 int gridSize = ccgSubSurf_getGridSize(ss); | |
1095 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1096 int i = 0; | |
1097 | |
1098 CCG_key_top_level(&key, ss); | |
1099 | |
1100 totface = ccgSubSurf_getNumFaces(ss); | |
1101 for (index = 0; index < totface; index++) { | |
1102 CCGFace *f = ccgdm->faceMap[index].face; | |
1103 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1104 | |
1105 vd = ccgSubSurf_getFaceCenterData(f); | |
1106 copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd)); | |
1107 normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd)); | |
1108 i++; | |
1109 ················ | |
1110 for (S = 0; S < numVerts; S++) { | |
1111 for (x = 1; x < gridSize - 1; x++, i++) { | |
1112 vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)
; | |
1113 copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd)); | |
1114 normal_float_to_short_v3(mvert[i].no, CCG_elem_n
o(&key, vd)); | |
1115 } | |
1116 } | |
1117 | |
1118 for (S = 0; S < numVerts; S++) { | |
1119 for (y = 1; y < gridSize - 1; y++) { | |
1120 for (x = 1; x < gridSize - 1; x++, i++) { | |
1121 vd = ccgSubSurf_getFaceGridData(ss, f, S
, x, y); | |
1122 copy_v3_v3(mvert[i].co, CCG_elem_co(&key
, vd)); | |
1123 normal_float_to_short_v3(mvert[i].no, CC
G_elem_no(&key, vd)); | |
1124 } | |
1125 } | |
1126 } | |
1127 } | |
1128 | |
1129 totedge = ccgSubSurf_getNumEdges(ss); | |
1130 for (index = 0; index < totedge; index++) { | |
1131 CCGEdge *e = ccgdm->edgeMap[index].edge; | |
1132 int x; | |
1133 | |
1134 for (x = 1; x < edgeSize - 1; x++, i++) { | |
1135 vd = ccgSubSurf_getEdgeData(ss, e, x); | |
1136 copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd)); | |
1137 /* This gives errors with -debug-fpe | |
1138 * the normals don't seem to be unit length. | |
1139 * this is most likely caused by edges with no | |
1140 * faces which are now zerod out, see comment in: | |
1141 * ccgSubSurf__calcVertNormals(), - campbell */ | |
1142 normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key,
vd)); | |
1143 } | |
1144 } | |
1145 | |
1146 totvert = ccgSubSurf_getNumVerts(ss); | |
1147 for (index = 0; index < totvert; index++) { | |
1148 CCGVert *v = ccgdm->vertMap[index].vert; | |
1149 | |
1150 vd = ccgSubSurf_getVertData(ss, v); | |
1151 copy_v3_v3(mvert[i].co, CCG_elem_co(&key, vd)); | |
1152 normal_float_to_short_v3(mvert[i].no, CCG_elem_no(&key, vd)); | |
1153 i++; | |
1154 } | |
1155 } | |
1156 | |
1157 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) | |
1158 { | |
1159 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1160 CCGSubSurf *ss = ccgdm->ss; | |
1161 int index; | |
1162 int totedge, totface; | |
1163 int gridSize = ccgSubSurf_getGridSize(ss); | |
1164 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1165 int i = 0; | |
1166 short *edgeFlags = ccgdm->edgeFlags; | |
1167 | |
1168 totface = ccgSubSurf_getNumFaces(ss); | |
1169 for (index = 0; index < totface; index++) { | |
1170 CCGFace *f = ccgdm->faceMap[index].face; | |
1171 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1172 | |
1173 for (S = 0; S < numVerts; S++) { | |
1174 for (x = 0; x < gridSize - 1; x++) { | |
1175 MEdge *med = &medge[i]; | |
1176 | |
1177 if (ccgdm->drawInteriorEdges) | |
1178 med->flag = ME_EDGEDRAW | ME_EDGERENDER; | |
1179 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize,
gridSize); | |
1180 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeS
ize, gridSize); | |
1181 i++; | |
1182 } | |
1183 | |
1184 for (x = 1; x < gridSize - 1; x++) { | |
1185 for (y = 0; y < gridSize - 1; y++) { | |
1186 MEdge *med; | |
1187 | |
1188 med = &medge[i]; | |
1189 if (ccgdm->drawInteriorEdges) | |
1190 med->flag = ME_EDGEDRAW | ME_EDG
ERENDER; | |
1191 med->v1 = getFaceIndex(ss, f, S, x, y, | |
1192 edgeSize, gridSiz
e); | |
1193 med->v2 = getFaceIndex(ss, f, S, x, y +
1, | |
1194 edgeSize, gridSiz
e); | |
1195 i++; | |
1196 | |
1197 med = &medge[i]; | |
1198 if (ccgdm->drawInteriorEdges) | |
1199 med->flag = ME_EDGEDRAW | ME_EDG
ERENDER; | |
1200 med->v1 = getFaceIndex(ss, f, S, y, x, | |
1201 edgeSize, gridSiz
e); | |
1202 med->v2 = getFaceIndex(ss, f, S, y + 1,
x, | |
1203 edgeSize, gridSiz
e); | |
1204 i++; | |
1205 } | |
1206 } | |
1207 } | |
1208 } | |
1209 | |
1210 totedge = ccgSubSurf_getNumEdges(ss); | |
1211 for (index = 0; index < totedge; index++) { | |
1212 CCGEdge *e = ccgdm->edgeMap[index].edge; | |
1213 unsigned int flags = 0; | |
1214 int x; | |
1215 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(
e)); | |
1216 | |
1217 if (!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; | |
1218 | |
1219 if (edgeFlags) { | |
1220 if (edgeIdx != -1) { | |
1221 flags |= (edgeFlags[index] & (ME_SEAM | ME_SHARP
)) | |
1222 | ME_EDGEDRAW | ME_EDGERENDER; | |
1223 } | |
1224 } | |
1225 else { | |
1226 flags |= ME_EDGEDRAW | ME_EDGERENDER; | |
1227 } | |
1228 | |
1229 for (x = 0; x < edgeSize - 1; x++) { | |
1230 MEdge *med = &medge[i]; | |
1231 med->v1 = getEdgeIndex(ss, e, x, edgeSize); | |
1232 med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize); | |
1233 med->flag = flags; | |
1234 i++; | |
1235 } | |
1236 } | |
1237 } | |
1238 | |
1239 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) | |
1240 { | |
1241 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1242 CCGSubSurf *ss = ccgdm->ss; | |
1243 int index; | |
1244 int totface; | |
1245 int gridSize = ccgSubSurf_getGridSize(ss); | |
1246 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1247 int i = 0; | |
1248 DMFlagMat *faceFlags = ccgdm->faceFlags; | |
1249 | |
1250 totface = ccgSubSurf_getNumFaces(ss); | |
1251 for (index = 0; index < totface; index++) { | |
1252 CCGFace *f = ccgdm->faceMap[index].face; | |
1253 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1254 /* keep types in sync with MFace, avoid many conversions */ | |
1255 char flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH; | |
1256 short mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0; | |
1257 | |
1258 for (S = 0; S < numVerts; S++) { | |
1259 for (y = 0; y < gridSize - 1; y++) { | |
1260 for (x = 0; x < gridSize - 1; x++) { | |
1261 MFace *mf = &mface[i]; | |
1262 mf->v1 = getFaceIndex(ss, f, S, x + 0, y
+ 0, | |
1263 edgeSize, gridSize
); | |
1264 mf->v2 = getFaceIndex(ss, f, S, x + 0, y
+ 1, | |
1265 edgeSize, gridSize
); | |
1266 mf->v3 = getFaceIndex(ss, f, S, x + 1, y
+ 1, | |
1267 edgeSize, gridSize
); | |
1268 mf->v4 = getFaceIndex(ss, f, S, x + 1, y
+ 0, | |
1269 edgeSize, gridSize
); | |
1270 mf->mat_nr = mat_nr; | |
1271 mf->flag = flag; | |
1272 | |
1273 i++; | |
1274 } | |
1275 } | |
1276 } | |
1277 } | |
1278 } | |
1279 | |
1280 static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop) | |
1281 { | |
1282 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1283 CCGSubSurf *ss = ccgdm->ss; | |
1284 int index; | |
1285 int totface; | |
1286 int gridSize = ccgSubSurf_getGridSize(ss); | |
1287 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1288 int i = 0; | |
1289 MLoop *mv; | |
1290 /* DMFlagMat *faceFlags = ccgdm->faceFlags; */ /* UNUSED */ | |
1291 | |
1292 if (!ccgdm->ehash) { | |
1293 MEdge *medge; | |
1294 | |
1295 ccgdm->ehash = BLI_edgehash_new(); | |
1296 medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm); | |
1297 | |
1298 for (i = 0; i < ccgdm->dm.numEdgeData; i++) { | |
1299 BLI_edgehash_insert(ccgdm->ehash, medge[i].v1, medge[i].
v2, SET_INT_IN_POINTER(i)); | |
1300 } | |
1301 } | |
1302 | |
1303 totface = ccgSubSurf_getNumFaces(ss); | |
1304 mv = mloop; | |
1305 for (index = 0; index < totface; index++) { | |
1306 CCGFace *f = ccgdm->faceMap[index].face; | |
1307 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1308 /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /*
UNUSED */ | |
1309 /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUS
ED */ | |
1310 | |
1311 for (S = 0; S < numVerts; S++) { | |
1312 for (y = 0; y < gridSize - 1; y++) { | |
1313 for (x = 0; x < gridSize - 1; x++) { | |
1314 int v1, v2, v3, v4; | |
1315 | |
1316 v1 = getFaceIndex(ss, f, S, x + 0, y + 0
, | |
1317 edgeSize, gridSize); | |
1318 | |
1319 v2 = getFaceIndex(ss, f, S, x + 0, y + 1
, | |
1320 edgeSize, gridSize); | |
1321 v3 = getFaceIndex(ss, f, S, x + 1, y + 1
, | |
1322 edgeSize, gridSize); | |
1323 v4 = getFaceIndex(ss, f, S, x + 1, y + 0
, | |
1324 edgeSize, gridSize); | |
1325 | |
1326 mv->v = v1; | |
1327 mv->e = GET_INT_FROM_POINTER(BLI_edgehas
h_lookup(ccgdm->ehash, v1, v2)); | |
1328 mv++, i++; | |
1329 | |
1330 mv->v = v2; | |
1331 mv->e = GET_INT_FROM_POINTER(BLI_edgehas
h_lookup(ccgdm->ehash, v2, v3)); | |
1332 mv++, i++; | |
1333 | |
1334 mv->v = v3; | |
1335 mv->e = GET_INT_FROM_POINTER(BLI_edgehas
h_lookup(ccgdm->ehash, v3, v4)); | |
1336 mv++, i++; | |
1337 | |
1338 mv->v = v4; | |
1339 mv->e = GET_INT_FROM_POINTER(BLI_edgehas
h_lookup(ccgdm->ehash, v4, v1)); | |
1340 mv++, i++; | |
1341 } | |
1342 } | |
1343 } | |
1344 } | |
1345 } | |
1346 | |
1347 static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly) | |
1348 { | |
1349 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1350 CCGSubSurf *ss = ccgdm->ss; | |
1351 int index; | |
1352 int totface; | |
1353 int gridSize = ccgSubSurf_getGridSize(ss); | |
1354 /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */ | |
1355 int i = 0, k = 0; | |
1356 DMFlagMat *faceFlags = ccgdm->faceFlags; | |
1357 | |
1358 totface = ccgSubSurf_getNumFaces(ss); | |
1359 for (index = 0; index < totface; index++) { | |
1360 CCGFace *f = ccgdm->faceMap[index].face; | |
1361 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1362 int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH; | |
1363 int mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0; | |
1364 | |
1365 for (S = 0; S < numVerts; S++) { | |
1366 for (y = 0; y < gridSize - 1; y++) { | |
1367 for (x = 0; x < gridSize - 1; x++) { | |
1368 MPoly *mp = &mpoly[i]; | |
1369 | |
1370 mp->mat_nr = mat_nr; | |
1371 mp->flag = flag; | |
1372 mp->loopstart = k; | |
1373 mp->totloop = 4; | |
1374 | |
1375 k += 4; | |
1376 i++; | |
1377 } | |
1378 } | |
1379 } | |
1380 } | |
1381 } | |
1382 | |
1383 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) | |
1384 { | |
1385 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1386 CCGSubSurf *ss = ccgdm->ss; | |
1387 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1388 int gridSize = ccgSubSurf_getGridSize(ss); | |
1389 int i; | |
1390 CCGVertIterator *vi; | |
1391 CCGEdgeIterator *ei; | |
1392 CCGFaceIterator *fi; | |
1393 CCGFace **faceMap2; | |
1394 CCGEdge **edgeMap2; | |
1395 CCGVert **vertMap2; | |
1396 int index, totvert, totedge, totface; | |
1397 ········ | |
1398 totvert = ccgSubSurf_getNumVerts(ss); | |
1399 vertMap2 = MEM_mallocN(totvert * sizeof(*vertMap2), "vertmap"); | |
1400 vi = ccgSubSurf_getVertIterator(ss); | |
1401 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { | |
1402 CCGVert *v = ccgVertIterator_getCurrent(vi); | |
1403 | |
1404 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))]
= v; | |
1405 } | |
1406 ccgVertIterator_free(vi); | |
1407 | |
1408 totedge = ccgSubSurf_getNumEdges(ss); | |
1409 edgeMap2 = MEM_mallocN(totedge * sizeof(*edgeMap2), "edgemap"); | |
1410 ei = ccgSubSurf_getEdgeIterator(ss); | |
1411 for (i = 0; !ccgEdgeIterator_isStopped(ei); i++, ccgEdgeIterator_next(ei
)) { | |
1412 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); | |
1413 | |
1414 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))]
= e; | |
1415 } | |
1416 | |
1417 totface = ccgSubSurf_getNumFaces(ss); | |
1418 faceMap2 = MEM_mallocN(totface * sizeof(*faceMap2), "facemap"); | |
1419 fi = ccgSubSurf_getFaceIterator(ss); | |
1420 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { | |
1421 CCGFace *f = ccgFaceIterator_getCurrent(fi); | |
1422 | |
1423 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))]
= f; | |
1424 } | |
1425 ccgFaceIterator_free(fi); | |
1426 | |
1427 i = 0; | |
1428 for (index = 0; index < totface; index++) { | |
1429 CCGFace *f = faceMap2[index]; | |
1430 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1431 | |
1432 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f)); | |
1433 ················ | |
1434 for (S = 0; S < numVerts; S++) { | |
1435 for (x = 1; x < gridSize - 1; x++) { | |
1436 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeD
ata(ss, f, S, x)); | |
1437 } | |
1438 } | |
1439 | |
1440 for (S = 0; S < numVerts; S++) { | |
1441 for (y = 1; y < gridSize - 1; y++) { | |
1442 for (x = 1; x < gridSize - 1; x++) { | |
1443 copy_v3_v3(cos[i++], ccgSubSurf_getFaceG
ridData(ss, f, S, x, y)); | |
1444 } | |
1445 } | |
1446 } | |
1447 } | |
1448 | |
1449 for (index = 0; index < totedge; index++) { | |
1450 CCGEdge *e = edgeMap2[index]; | |
1451 int x; | |
1452 | |
1453 for (x = 1; x < edgeSize - 1; x++) { | |
1454 copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x)); | |
1455 } | |
1456 } | |
1457 | |
1458 for (index = 0; index < totvert; index++) { | |
1459 CCGVert *v = vertMap2[index]; | |
1460 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v)); | |
1461 } | |
1462 | |
1463 MEM_freeN(vertMap2); | |
1464 MEM_freeN(edgeMap2); | |
1465 MEM_freeN(faceMap2); | |
1466 } | |
1467 | |
1468 static void ccgDM_foreachMappedVert( | |
1469 DerivedMesh *dm, | |
1470 void (*func)(void *userData, int index, const float co[3], const float no_f[
3], const short no_s[3]), | |
1471 void *userData) | |
1472 { | |
1473 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1474 CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss); | |
1475 CCGKey key; | |
1476 CCG_key_top_level(&key, ccgdm->ss); | |
1477 | |
1478 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { | |
1479 CCGVert *v = ccgVertIterator_getCurrent(vi); | |
1480 CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v); | |
1481 int index = ccgDM_getVertMapIndex(ccgdm->ss, v); | |
1482 | |
1483 if (index != -1) | |
1484 func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no
(&key, vd), NULL); | |
1485 } | |
1486 | |
1487 ccgVertIterator_free(vi); | |
1488 } | |
1489 | |
1490 static void ccgDM_foreachMappedEdge( | |
1491 DerivedMesh *dm, | |
1492 void (*func)(void *userData, int index, const float v0co[3], const float v1c
o[3]), | |
1493 void *userData) | |
1494 { | |
1495 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1496 CCGSubSurf *ss = ccgdm->ss; | |
1497 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); | |
1498 CCGKey key; | |
1499 int i, edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1500 | |
1501 CCG_key_top_level(&key, ss); | |
1502 | |
1503 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { | |
1504 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); | |
1505 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); | |
1506 int index = ccgDM_getEdgeMapIndex(ss, e); | |
1507 | |
1508 if (index != -1) { | |
1509 for (i = 0; i < edgeSize - 1; i++) | |
1510 func(userData, index, CCG_elem_offset_co(&key, e
dgeData, i), CCG_elem_offset_co(&key, edgeData, i + 1)); | |
1511 } | |
1512 } | |
1513 | |
1514 ccgEdgeIterator_free(ei); | |
1515 } | |
1516 | |
1517 static void ccgDM_drawVerts(DerivedMesh *dm) | |
1518 { | |
1519 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1520 CCGSubSurf *ss = ccgdm->ss; | |
1521 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1522 int gridSize = ccgSubSurf_getGridSize(ss); | |
1523 CCGVertIterator *vi; | |
1524 CCGEdgeIterator *ei; | |
1525 CCGFaceIterator *fi; | |
1526 | |
1527 glBegin(GL_POINTS); | |
1528 vi = ccgSubSurf_getVertIterator(ss); | |
1529 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { | |
1530 CCGVert *v = ccgVertIterator_getCurrent(vi); | |
1531 glVertex3fv(ccgSubSurf_getVertData(ss, v)); | |
1532 } | |
1533 ccgVertIterator_free(vi); | |
1534 | |
1535 ei = ccgSubSurf_getEdgeIterator(ss); | |
1536 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { | |
1537 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); | |
1538 int x; | |
1539 | |
1540 for (x = 1; x < edgeSize - 1; x++) | |
1541 glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x)); | |
1542 } | |
1543 ccgEdgeIterator_free(ei); | |
1544 | |
1545 fi = ccgSubSurf_getFaceIterator(ss); | |
1546 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { | |
1547 CCGFace *f = ccgFaceIterator_getCurrent(fi); | |
1548 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1549 | |
1550 glVertex3fv(ccgSubSurf_getFaceCenterData(f)); | |
1551 for (S = 0; S < numVerts; S++) | |
1552 for (x = 1; x < gridSize - 1; x++) | |
1553 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f
, S, x)); | |
1554 for (S = 0; S < numVerts; S++) | |
1555 for (y = 1; y < gridSize - 1; y++) | |
1556 for (x = 1; x < gridSize - 1; x++) | |
1557 glVertex3fv(ccgSubSurf_getFaceGridData(s
s, f, S, x, y)); | |
1558 } | |
1559 ccgFaceIterator_free(fi); | |
1560 glEnd(); | |
1561 } | |
1562 | |
1563 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm) | |
1564 { | |
1565 if (ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) { | |
1566 CCGFace **faces; | |
1567 int totface; | |
1568 | |
1569 BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &tot
face); | |
1570 if (totface) { | |
1571 ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface)
; | |
1572 ccgSubSurf_updateNormals(ccgdm->ss, faces, totface); | |
1573 MEM_freeN(faces); | |
1574 } | |
1575 } | |
1576 } | |
1577 | |
1578 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdge
s) | |
1579 { | |
1580 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1581 CCGSubSurf *ss = ccgdm->ss; | |
1582 CCGKey key; | |
1583 int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1584 int totedge = ccgSubSurf_getNumEdges(ss); | |
1585 int gridSize = ccgSubSurf_getGridSize(ss); | |
1586 int useAging; | |
1587 | |
1588 CCG_key_top_level(&key, ss); | |
1589 ccgdm_pbvh_update(ccgdm); | |
1590 | |
1591 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); | |
1592 | |
1593 for (j = 0; j < totedge; j++) { | |
1594 CCGEdge *e = ccgdm->edgeMap[j].edge; | |
1595 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); | |
1596 | |
1597 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e)) | |
1598 continue; | |
1599 | |
1600 if (!drawAllEdges && ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] &
ME_EDGEDRAW)) | |
1601 continue; | |
1602 | |
1603 if (useAging && !(G.f & G_BACKBUFSEL)) { | |
1604 int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4; | |
1605 glColor3ub(0, ageCol > 0 ? ageCol : 0, 0); | |
1606 } | |
1607 | |
1608 glBegin(GL_LINE_STRIP); | |
1609 for (i = 0; i < edgeSize - 1; i++) { | |
1610 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i)); | |
1611 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1)); | |
1612 } | |
1613 glEnd(); | |
1614 } | |
1615 | |
1616 if (useAging && !(G.f & G_BACKBUFSEL)) { | |
1617 glColor3ub(0, 0, 0); | |
1618 } | |
1619 | |
1620 if (ccgdm->drawInteriorEdges) { | |
1621 int totface = ccgSubSurf_getNumFaces(ss); | |
1622 | |
1623 for (j = 0; j < totface; j++) { | |
1624 CCGFace *f = ccgdm->faceMap[j].face; | |
1625 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1626 | |
1627 for (S = 0; S < numVerts; S++) { | |
1628 CCGElem *faceGridData = ccgSubSurf_getFaceGridDa
taArray(ss, f, S); | |
1629 | |
1630 glBegin(GL_LINE_STRIP); | |
1631 for (x = 0; x < gridSize; x++) | |
1632 glVertex3fv(CCG_elem_offset_co(&key, fac
eGridData, x)); | |
1633 glEnd(); | |
1634 for (y = 1; y < gridSize - 1; y++) { | |
1635 glBegin(GL_LINE_STRIP); | |
1636 for (x = 0; x < gridSize; x++) | |
1637 glVertex3fv(CCG_grid_elem_co(&ke
y, faceGridData, x, y)); | |
1638 glEnd(); | |
1639 } | |
1640 for (x = 1; x < gridSize - 1; x++) { | |
1641 glBegin(GL_LINE_STRIP); | |
1642 for (y = 0; y < gridSize; y++) | |
1643 glVertex3fv(CCG_grid_elem_co(&ke
y, faceGridData, x, y)); | |
1644 glEnd(); | |
1645 } | |
1646 } | |
1647 } | |
1648 } | |
1649 } | |
1650 | |
1651 static void ccgDM_drawLooseEdges(DerivedMesh *dm) | |
1652 { | |
1653 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1654 CCGSubSurf *ss = ccgdm->ss; | |
1655 CCGKey key; | |
1656 int totedge = ccgSubSurf_getNumEdges(ss); | |
1657 int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1658 | |
1659 CCG_key_top_level(&key, ss); | |
1660 | |
1661 for (j = 0; j < totedge; j++) { | |
1662 CCGEdge *e = ccgdm->edgeMap[j].edge; | |
1663 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); | |
1664 | |
1665 if (!ccgSubSurf_getEdgeNumFaces(e)) { | |
1666 glBegin(GL_LINE_STRIP); | |
1667 for (i = 0; i < edgeSize - 1; i++) { | |
1668 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i
)); | |
1669 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i
+ 1)); | |
1670 } | |
1671 glEnd(); | |
1672 } | |
1673 } | |
1674 } | |
1675 | |
1676 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d) | |
1677 { | |
1678 float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2]; | |
1679 float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2]; | |
1680 float no[3]; | |
1681 | |
1682 no[0] = b_dY * a_cZ - b_dZ * a_cY; | |
1683 no[1] = b_dZ * a_cX - b_dX * a_cZ; | |
1684 no[2] = b_dX * a_cY - b_dY * a_cX; | |
1685 | |
1686 /* don't normalize, GL_NORMALIZE is enabled */ | |
1687 glNormal3fv(no); | |
1688 } | |
1689 | |
1690 /* Only used by non-editmesh types */ | |
1691 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
[4], int fast, DMSetMaterial setMaterial) | |
1692 { | |
1693 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1694 CCGSubSurf *ss = ccgdm->ss; | |
1695 CCGKey key; | |
1696 int gridSize = ccgSubSurf_getGridSize(ss); | |
1697 DMFlagMat *faceFlags = ccgdm->faceFlags; | |
1698 int step = (fast) ? gridSize - 1 : 1; | |
1699 int i, totface = ccgSubSurf_getNumFaces(ss); | |
1700 int drawcurrent = 0, matnr = -1, shademodel = -1; | |
1701 | |
1702 CCG_key_top_level(&key, ss); | |
1703 ccgdm_pbvh_update(ccgdm); | |
1704 | |
1705 if (ccgdm->pbvh && ccgdm->multires.mmd && !fast) { | |
1706 if (dm->numTessFaceData) { | |
1707 BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
setMaterial); | |
1708 glShadeModel(GL_FLAT); | |
1709 } | |
1710 | |
1711 return; | |
1712 } | |
1713 | |
1714 for (i = 0; i < totface; i++) { | |
1715 CCGFace *f = ccgdm->faceMap[i].face; | |
1716 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1717 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)
); | |
1718 int new_matnr, new_shademodel; | |
1719 | |
1720 if (faceFlags) { | |
1721 new_shademodel = (faceFlags[index].flag & ME_SMOOTH) ? G
L_SMOOTH : GL_FLAT; | |
1722 new_matnr = faceFlags[index].mat_nr; | |
1723 } | |
1724 else { | |
1725 new_shademodel = GL_SMOOTH; | |
1726 new_matnr = 0; | |
1727 } | |
1728 ················ | |
1729 if (shademodel != new_shademodel || matnr != new_matnr) { | |
1730 matnr = new_matnr; | |
1731 shademodel = new_shademodel; | |
1732 | |
1733 drawcurrent = setMaterial(matnr + 1, NULL); | |
1734 | |
1735 glShadeModel(shademodel); | |
1736 } | |
1737 | |
1738 if (!drawcurrent) | |
1739 continue; | |
1740 | |
1741 for (S = 0; S < numVerts; S++) { | |
1742 CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(
ss, f, S); | |
1743 | |
1744 if (shademodel == GL_SMOOTH) { | |
1745 for (y = 0; y < gridSize - 1; y += step) { | |
1746 glBegin(GL_QUAD_STRIP); | |
1747 for (x = 0; x < gridSize; x += step) { | |
1748 CCGElem *a = CCG_grid_elem(&key,
faceGridData, x, y + 0); | |
1749 CCGElem *b = CCG_grid_elem(&key,
faceGridData, x, y + step); | |
1750 | |
1751 glNormal3fv(CCG_elem_no(&key, a)
); | |
1752 glVertex3fv(CCG_elem_co(&key, a)
); | |
1753 glNormal3fv(CCG_elem_no(&key, b)
); | |
1754 glVertex3fv(CCG_elem_co(&key, b)
); | |
1755 } | |
1756 glEnd(); | |
1757 } | |
1758 } | |
1759 else { | |
1760 glBegin(GL_QUADS); | |
1761 for (y = 0; y < gridSize - 1; y += step) { | |
1762 for (x = 0; x < gridSize - 1; x += step)
{ | |
1763 float *a = CCG_grid_elem_co(&key
, faceGridData, x, y + 0); | |
1764 float *b = CCG_grid_elem_co(&key
, faceGridData, x + step, y + 0); | |
1765 float *c = CCG_grid_elem_co(&key
, faceGridData, x + step, y + step); | |
1766 float *d = CCG_grid_elem_co(&key
, faceGridData, x, y + step); | |
1767 | |
1768 ccgDM_glNormalFast(a, b, c, d); | |
1769 | |
1770 glVertex3fv(d); | |
1771 glVertex3fv(c); | |
1772 glVertex3fv(b); | |
1773 glVertex3fv(a); | |
1774 } | |
1775 } | |
1776 glEnd(); | |
1777 } | |
1778 } | |
1779 } | |
1780 } | |
1781 | |
1782 /* Only used by non-editmesh types */ | |
1783 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, | |
1784 DMSetMaterial setMaterial, | |
1785 DMSetDrawOptions setDrawOptions, | |
1786 void *userData) | |
1787 { | |
1788 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1789 CCGSubSurf *ss = ccgdm->ss; | |
1790 CCGKey key; | |
1791 GPUVertexAttribs gattribs; | |
1792 DMVertexAttribs attribs = {{{NULL}}}; | |
1793 /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ | |
1794 int gridSize = ccgSubSurf_getGridSize(ss); | |
1795 int gridFaces = gridSize - 1; | |
1796 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1797 DMFlagMat *faceFlags = ccgdm->faceFlags; | |
1798 int a, b, i, doDraw, numVerts, matnr, new_matnr, totface; | |
1799 | |
1800 CCG_key_top_level(&key, ss); | |
1801 ccgdm_pbvh_update(ccgdm); | |
1802 | |
1803 doDraw = 0; | |
1804 matnr = -1; | |
1805 | |
1806 #define PASSATTRIB(dx, dy, vert) {
\ | |
1807 if (attribs.totorco) {
\ | |
1808 index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSiz
e); \ | |
1809 glVertexAttrib3fvARB(attribs.orco.gl_index, attribs.orco.array[i
ndex]); \ | |
1810 }
\ | |
1811 for (b = 0; b < attribs.tottface; b++) {
\ | |
1812 MTFace *tf = &attribs.tface[b].array[a];
\ | |
1813 glVertexAttrib2fvARB(attribs.tface[b].gl_index, tf->uv[vert]);
\ | |
1814 }
\ | |
1815 for (b = 0; b < attribs.totmcol; b++) {
\ | |
1816 MCol *cp = &attribs.mcol[b].array[a * 4 + vert];
\ | |
1817 GLubyte col[4];
\ | |
1818 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
\ | |
1819 glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, col);
\ | |
1820 }
\ | |
1821 if (attribs.tottang) {
\ | |
1822 float *tang = attribs.tang.array[a * 4 + vert];
\ | |
1823 glVertexAttrib4fvARB(attribs.tang.gl_index, tang);
\ | |
1824 }
\ | |
1825 } | |
1826 | |
1827 totface = ccgSubSurf_getNumFaces(ss); | |
1828 for (a = 0, i = 0; i < totface; i++) { | |
1829 CCGFace *f = ccgdm->faceMap[i].face; | |
1830 int S, x, y, drawSmooth; | |
1831 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)
); | |
1832 int origIndex = ccgDM_getFaceMapIndex(ss, f); | |
1833 ················ | |
1834 numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1835 | |
1836 if (faceFlags) { | |
1837 drawSmooth = (faceFlags[index].flag & ME_SMOOTH); | |
1838 new_matnr = faceFlags[index].mat_nr + 1; | |
1839 } | |
1840 else { | |
1841 drawSmooth = 1; | |
1842 new_matnr = 1; | |
1843 } | |
1844 | |
1845 if (new_matnr != matnr) { | |
1846 doDraw = setMaterial(matnr = new_matnr, &gattribs); | |
1847 if (doDraw) | |
1848 DM_vertex_attributes_from_gpu(dm, &gattribs, &at
tribs); | |
1849 } | |
1850 | |
1851 if (!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE)
&& | |
1852 (setDrawOptions(userData, origIndex) == DM_DRAW_
OPTION_SKIP))) | |
1853 { | |
1854 a += gridFaces * gridFaces * numVerts; | |
1855 continue; | |
1856 } | |
1857 | |
1858 glShadeModel(drawSmooth ? GL_SMOOTH: GL_FLAT); | |
1859 for (S = 0; S < numVerts; S++) { | |
1860 CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(
ss, f, S); | |
1861 CCGElem *vda, *vdb; | |
1862 | |
1863 if (drawSmooth) { | |
1864 for (y = 0; y < gridFaces; y++) { | |
1865 glBegin(GL_QUAD_STRIP); | |
1866 for (x = 0; x < gridFaces; x++) { | |
1867 vda = CCG_grid_elem(&key, faceGr
idData, x, y + 0); | |
1868 vdb = CCG_grid_elem(&key, faceGr
idData, x, y + 1); | |
1869 ················································ | |
1870 PASSATTRIB(0, 0, 0); | |
1871 glNormal3fv(CCG_elem_no(&key, vd
a)); | |
1872 glVertex3fv(CCG_elem_co(&key, vd
a)); | |
1873 | |
1874 PASSATTRIB(0, 1, 1); | |
1875 glNormal3fv(CCG_elem_no(&key, vd
b)); | |
1876 glVertex3fv(CCG_elem_co(&key, vd
b)); | |
1877 | |
1878 if (x != gridFaces - 1) | |
1879 a++; | |
1880 } | |
1881 | |
1882 vda = CCG_grid_elem(&key, faceGridData,
x, y + 0); | |
1883 vdb = CCG_grid_elem(&key, faceGridData,
x, y + 1); | |
1884 | |
1885 PASSATTRIB(0, 0, 3); | |
1886 glNormal3fv(CCG_elem_no(&key, vda)); | |
1887 glVertex3fv(CCG_elem_co(&key, vda)); | |
1888 | |
1889 PASSATTRIB(0, 1, 2); | |
1890 glNormal3fv(CCG_elem_no(&key, vdb)); | |
1891 glVertex3fv(CCG_elem_co(&key, vdb)); | |
1892 | |
1893 glEnd(); | |
1894 | |
1895 a++; | |
1896 } | |
1897 } | |
1898 else { | |
1899 glBegin(GL_QUADS); | |
1900 for (y = 0; y < gridFaces; y++) { | |
1901 for (x = 0; x < gridFaces; x++) { | |
1902 float *aco = CCG_grid_elem_co(&k
ey, faceGridData, x, y); | |
1903 float *bco = CCG_grid_elem_co(&k
ey, faceGridData, x + 1, y); | |
1904 float *cco = CCG_grid_elem_co(&k
ey, faceGridData, x + 1, y + 1); | |
1905 float *dco = CCG_grid_elem_co(&k
ey, faceGridData, x, y + 1); | |
1906 | |
1907 ccgDM_glNormalFast(aco, bco, cco
, dco); | |
1908 | |
1909 PASSATTRIB(0, 1, 1); | |
1910 glVertex3fv(dco); | |
1911 PASSATTRIB(1, 1, 2); | |
1912 glVertex3fv(cco); | |
1913 PASSATTRIB(1, 0, 3); | |
1914 glVertex3fv(bco); | |
1915 PASSATTRIB(0, 0, 0); | |
1916 glVertex3fv(aco); | |
1917 ················································ | |
1918 a++; | |
1919 } | |
1920 } | |
1921 glEnd(); | |
1922 } | |
1923 } | |
1924 } | |
1925 | |
1926 #undef PASSATTRIB | |
1927 } | |
1928 | |
1929 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial) | |
1930 { | |
1931 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); | |
1932 } | |
1933 | |
1934 /* Only used by non-editmesh types */ | |
1935 static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *
userData, int, void *attribs), int (*setFace)(void *userData, int index), void *
userData) | |
1936 { | |
1937 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
1938 CCGSubSurf *ss = ccgdm->ss; | |
1939 CCGKey key; | |
1940 GPUVertexAttribs gattribs; | |
1941 DMVertexAttribs attribs = {{{NULL}}}; | |
1942 int gridSize = ccgSubSurf_getGridSize(ss); | |
1943 int gridFaces = gridSize - 1; | |
1944 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
1945 DMFlagMat *faceFlags = ccgdm->faceFlags; | |
1946 int a, b, i, numVerts, matnr, new_matnr, totface; | |
1947 | |
1948 CCG_key_top_level(&key, ss); | |
1949 ccgdm_pbvh_update(ccgdm); | |
1950 | |
1951 matnr = -1; | |
1952 | |
1953 #define PASSATTRIB(dx, dy, vert) {
\ | |
1954 if (attribs.totorco) {
\ | |
1955 index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSiz
e); \ | |
1956 if (attribs.orco.gl_texco)
\ | |
1957 glTexCoord3fv(attribs.orco.array[index]);
\ | |
1958 else
\ | |
1959 glVertexAttrib3fvARB(attribs.orco.gl_index, attribs.orco
.array[index]); \ | |
1960 }
\ | |
1961 for (b = 0; b < attribs.tottface; b++) {
\ | |
1962 MTFace *tf = &attribs.tface[b].array[a];
\ | |
1963 if (attribs.tface[b].gl_texco)
\ | |
1964 glTexCoord2fv(tf->uv[vert]);
\ | |
1965 else
\ | |
1966 glVertexAttrib2fvARB(attribs.tface[b].gl_index, tf->uv[v
ert]); \ | |
1967 }
\ | |
1968 for (b = 0; b < attribs.totmcol; b++) {
\ | |
1969 MCol *cp = &attribs.mcol[b].array[a * 4 + vert];
\ | |
1970 GLubyte col[4];
\ | |
1971 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
\ | |
1972 glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, col);
\ | |
1973 }
\ | |
1974 if (attribs.tottang) {
\ | |
1975 float *tang = attribs.tang.array[a * 4 + vert];
\ | |
1976 glVertexAttrib4fvARB(attribs.tang.gl_index, tang);
\ | |
1977 }
\ | |
1978 } | |
1979 | |
1980 totface = ccgSubSurf_getNumFaces(ss); | |
1981 for (a = 0, i = 0; i < totface; i++) { | |
1982 CCGFace *f = ccgdm->faceMap[i].face; | |
1983 int S, x, y, drawSmooth; | |
1984 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)
); | |
1985 int origIndex = ccgDM_getFaceMapIndex(ss, f); | |
1986 ················ | |
1987 numVerts = ccgSubSurf_getFaceNumVerts(f); | |
1988 | |
1989 /* get flags */ | |
1990 if (faceFlags) { | |
1991 drawSmooth = (faceFlags[index].flag & ME_SMOOTH); | |
1992 new_matnr = faceFlags[index].mat_nr + 1; | |
1993 } | |
1994 else { | |
1995 drawSmooth = 1; | |
1996 new_matnr = 1; | |
1997 } | |
1998 | |
1999 /* material */ | |
2000 if (new_matnr != matnr) { | |
2001 setMaterial(userData, matnr = new_matnr, &gattribs); | |
2002 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); | |
2003 } | |
2004 | |
2005 /* face hiding */ | |
2006 if ((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userDa
ta, origIndex))) { | |
2007 a += gridFaces * gridFaces * numVerts; | |
2008 continue; | |
2009 } | |
2010 | |
2011 /* draw face*/ | |
2012 glShadeModel(drawSmooth ? GL_SMOOTH: GL_FLAT); | |
2013 for (S = 0; S < numVerts; S++) { | |
2014 CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(
ss, f, S); | |
2015 CCGElem *vda, *vdb; | |
2016 | |
2017 if (drawSmooth) { | |
2018 for (y = 0; y < gridFaces; y++) { | |
2019 glBegin(GL_QUAD_STRIP); | |
2020 for (x = 0; x < gridFaces; x++) { | |
2021 vda = CCG_grid_elem(&key, faceGr
idData, x, y); | |
2022 vdb = CCG_grid_elem(&key, faceGr
idData, x, y + 1); | |
2023 ················································ | |
2024 PASSATTRIB(0, 0, 0); | |
2025 glNormal3fv(CCG_elem_no(&key, vd
a)); | |
2026 glVertex3fv(CCG_elem_co(&key, vd
a)); | |
2027 | |
2028 PASSATTRIB(0, 1, 1); | |
2029 glNormal3fv(CCG_elem_no(&key, vd
b)); | |
2030 glVertex3fv(CCG_elem_co(&key, vd
b)); | |
2031 | |
2032 if (x != gridFaces - 1) | |
2033 a++; | |
2034 } | |
2035 | |
2036 vda = CCG_grid_elem(&key, faceGridData,
x, y + 0); | |
2037 vdb = CCG_grid_elem(&key, faceGridData,
x, y + 1); | |
2038 | |
2039 PASSATTRIB(0, 0, 3); | |
2040 glNormal3fv(CCG_elem_no(&key, vda)); | |
2041 glVertex3fv(CCG_elem_co(&key, vda)); | |
2042 | |
2043 PASSATTRIB(0, 1, 2); | |
2044 glNormal3fv(CCG_elem_no(&key, vdb)); | |
2045 glVertex3fv(CCG_elem_co(&key, vdb)); | |
2046 | |
2047 glEnd(); | |
2048 | |
2049 a++; | |
2050 } | |
2051 } | |
2052 else { | |
2053 glBegin(GL_QUADS); | |
2054 for (y=0; y < gridFaces; y++) { | |
2055 for (x=0; x < gridFaces; x++) { | |
2056 float *aco = CCG_grid_elem_co(&k
ey, faceGridData, x, y + 0); | |
2057 float *bco = CCG_grid_elem_co(&k
ey, faceGridData, x + 1, y + 0); | |
2058 float *cco = CCG_grid_elem_co(&k
ey, faceGridData, x + 1, y + 1); | |
2059 float *dco = CCG_grid_elem_co(&k
ey, faceGridData, x, y + 1); | |
2060 | |
2061 ccgDM_glNormalFast(aco, bco, cco
, dco); | |
2062 | |
2063 PASSATTRIB(0, 1, 1); | |
2064 glVertex3fv(dco); | |
2065 PASSATTRIB(1, 1, 2); | |
2066 glVertex3fv(cco); | |
2067 PASSATTRIB(1, 0, 3); | |
2068 glVertex3fv(bco); | |
2069 PASSATTRIB(0, 0, 0); | |
2070 glVertex3fv(aco); | |
2071 ················································ | |
2072 a++; | |
2073 } | |
2074 } | |
2075 glEnd(); | |
2076 } | |
2077 } | |
2078 } | |
2079 | |
2080 #undef PASSATTRIB | |
2081 } | |
2082 | |
2083 static void ccgDM_drawFacesTex_common(DerivedMesh *dm, | |
2084 DMSetDrawOptionsTex drawParams, | |
2085 DMSetDrawOptions drawParamsMapped, | |
2086 DMCompareDrawOptions compareDrawOptions, | |
2087 void *userData) | |
2088 { | |
2089 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
2090 CCGSubSurf *ss = ccgdm->ss; | |
2091 CCGKey key; | |
2092 MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); | |
2093 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); | |
2094 DMFlagMat *faceFlags = ccgdm->faceFlags; | |
2095 DMDrawOption draw_option; | |
2096 int i, totface, gridSize = ccgSubSurf_getGridSize(ss); | |
2097 int gridFaces = gridSize - 1; | |
2098 | |
2099 (void) compareDrawOptions; | |
2100 | |
2101 CCG_key_top_level(&key, ss); | |
2102 ccgdm_pbvh_update(ccgdm); | |
2103 | |
2104 if (!mcol) | |
2105 mcol = dm->getTessFaceDataArray(dm, CD_MCOL); | |
2106 | |
2107 if (!mcol) | |
2108 mcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL); | |
2109 | |
2110 totface = ccgSubSurf_getNumFaces(ss); | |
2111 for (i = 0; i < totface; i++) { | |
2112 CCGFace *f = ccgdm->faceMap[i].face; | |
2113 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
2114 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); | |
2115 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandl
e(f)); | |
2116 unsigned char *cp = NULL; | |
2117 int mat_nr; | |
2118 | |
2119 if (faceFlags) { | |
2120 drawSmooth = (faceFlags[origIndex].flag & ME_SMOOTH); | |
2121 mat_nr = faceFlags[origIndex].mat_nr; | |
2122 } | |
2123 else { | |
2124 drawSmooth = 1; | |
2125 mat_nr = 0; | |
2126 } | |
2127 | |
2128 if (drawParams) | |
2129 draw_option = drawParams(tf, (mcol != NULL), mat_nr); | |
2130 else if (index != ORIGINDEX_NONE) | |
2131 draw_option = (drawParamsMapped) ? drawParamsMapped(user
Data, index) : DM_DRAW_OPTION_NORMAL; | |
2132 else | |
2133 draw_option = GPU_enable_material(mat_nr, NULL) ? DM_DRA
W_OPTION_NORMAL : DM_DRAW_OPTION_SKIP; | |
2134 | |
2135 | |
2136 if (draw_option == DM_DRAW_OPTION_SKIP) { | |
2137 if (tf) tf += gridFaces * gridFaces * numVerts; | |
2138 if (mcol) mcol += gridFaces * gridFaces * numVerts * 4; | |
2139 continue; | |
2140 } | |
2141 | |
2142 /* flag 1 == use vertex colors */ | |
2143 if (mcol) { | |
2144 if (draw_option != DM_DRAW_OPTION_NO_MCOL) | |
2145 cp = (unsigned char *)mcol; | |
2146 mcol += gridFaces * gridFaces * numVerts * 4; | |
2147 } | |
2148 | |
2149 for (S = 0; S < numVerts; S++) { | |
2150 CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(
ss, f, S); | |
2151 CCGElem *a, *b; | |
2152 | |
2153 if (drawSmooth) { | |
2154 glShadeModel(GL_SMOOTH); | |
2155 for (y = 0; y < gridFaces; y++) { | |
2156 glBegin(GL_QUAD_STRIP); | |
2157 for (x=0; x<gridFaces; x++) { | |
2158 a = CCG_grid_elem(&key, faceGrid
Data, x, y + 0); | |
2159 b = CCG_grid_elem(&key, faceGrid
Data, x, y + 1); | |
2160 | |
2161 if (tf) glTexCoord2fv(tf->uv[0])
; | |
2162 if (cp) glColor3ub(cp[3], cp[2],
cp[1]); | |
2163 glNormal3fv(CCG_elem_no(&key, a)
); | |
2164 glVertex3fv(CCG_elem_co(&key, a)
); | |
2165 | |
2166 if (tf) glTexCoord2fv(tf->uv[1])
; | |
2167 if (cp) glColor3ub(cp[7], cp[6],
cp[5]); | |
2168 glNormal3fv(CCG_elem_no(&key, b)
); | |
2169 glVertex3fv(CCG_elem_co(&key, b)
); | |
2170 ················································ | |
2171 if (x != gridFaces - 1) { | |
2172 if (tf) tf++; | |
2173 if (cp) cp += 16; | |
2174 } | |
2175 } | |
2176 | |
2177 a = CCG_grid_elem(&key, faceGridData, x,
y + 0); | |
2178 b = CCG_grid_elem(&key, faceGridData, x,
y + 1); | |
2179 | |
2180 if (tf) glTexCoord2fv(tf->uv[3]); | |
2181 if (cp) glColor3ub(cp[15], cp[14], cp[13
]); | |
2182 glNormal3fv(CCG_elem_no(&key, a)); | |
2183 glVertex3fv(CCG_elem_co(&key, a)); | |
2184 | |
2185 if (tf) glTexCoord2fv(tf->uv[2]); | |
2186 if (cp) glColor3ub(cp[11], cp[10], cp[9]
); | |
2187 glNormal3fv(CCG_elem_no(&key, b)); | |
2188 glVertex3fv(CCG_elem_co(&key, b)); | |
2189 | |
2190 if (tf) tf++; | |
2191 if (cp) cp += 16; | |
2192 | |
2193 glEnd(); | |
2194 } | |
2195 } | |
2196 else { | |
2197 glShadeModel((cp)? GL_SMOOTH: GL_FLAT); | |
2198 glBegin(GL_QUADS); | |
2199 for (y = 0; y < gridFaces; y++) { | |
2200 for (x = 0; x < gridFaces; x++) { | |
2201 float *a_co = CCG_grid_elem_co(&
key, faceGridData, x, y + 0); | |
2202 float *b_co = CCG_grid_elem_co(&
key, faceGridData, x + 1, y + 0); | |
2203 float *c_co = CCG_grid_elem_co(&
key, faceGridData, x + 1, y + 1); | |
2204 float *d_co = CCG_grid_elem_co(&
key, faceGridData, x, y + 1); | |
2205 | |
2206 ccgDM_glNormalFast(a_co, b_co, c
_co, d_co); | |
2207 | |
2208 if (tf) glTexCoord2fv(tf->uv[1])
; | |
2209 if (cp) glColor3ub(cp[7], cp[6],
cp[5]); | |
2210 glVertex3fv(d_co); | |
2211 | |
2212 if (tf) glTexCoord2fv(tf->uv[2])
; | |
2213 if (cp) glColor3ub(cp[11], cp[10
], cp[9]); | |
2214 glVertex3fv(c_co); | |
2215 | |
2216 if (tf) glTexCoord2fv(tf->uv[3])
; | |
2217 if (cp) glColor3ub(cp[15], cp[14
], cp[13]); | |
2218 glVertex3fv(b_co); | |
2219 | |
2220 if (tf) glTexCoord2fv(tf->uv[0])
; | |
2221 if (cp) glColor3ub(cp[3], cp[2],
cp[1]); | |
2222 glVertex3fv(a_co); | |
2223 | |
2224 if (tf) tf++; | |
2225 if (cp) cp += 16; | |
2226 } | |
2227 } | |
2228 glEnd(); | |
2229 } | |
2230 } | |
2231 } | |
2232 } | |
2233 | |
2234 static void ccgDM_drawFacesTex(DerivedMesh *dm, | |
2235 DMSetDrawOptionsTex setDrawOptions, | |
2236 DMCompareDrawOptions compareDrawOptions, | |
2237 void *userData) | |
2238 { | |
2239 ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions,
userData); | |
2240 } | |
2241 | |
2242 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, | |
2243 DMSetDrawOptions setDrawOptions, | |
2244 DMCompareDrawOptions compareDrawOptions, | |
2245 void *userData) | |
2246 { | |
2247 ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions,
userData); | |
2248 } | |
2249 | |
2250 static void ccgDM_drawUVEdges(DerivedMesh *dm) | |
2251 { | |
2252 | |
2253 MFace *mf = dm->getTessFaceArray(dm); | |
2254 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); | |
2255 int i; | |
2256 ········ | |
2257 if (tf) { | |
2258 glBegin(GL_LINES); | |
2259 for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) { | |
2260 if (!(mf->flag & ME_HIDE)) { | |
2261 glVertex2fv(tf->uv[0]); | |
2262 glVertex2fv(tf->uv[1]); | |
2263 ········ | |
2264 glVertex2fv(tf->uv[1]); | |
2265 glVertex2fv(tf->uv[2]); | |
2266 ········ | |
2267 if (!mf->v4) { | |
2268 glVertex2fv(tf->uv[2]); | |
2269 glVertex2fv(tf->uv[0]); | |
2270 } | |
2271 else { | |
2272 glVertex2fv(tf->uv[2]); | |
2273 glVertex2fv(tf->uv[3]); | |
2274 ········ | |
2275 glVertex2fv(tf->uv[3]); | |
2276 glVertex2fv(tf->uv[0]); | |
2277 } | |
2278 } | |
2279 } | |
2280 glEnd(); | |
2281 } | |
2282 } | |
2283 | |
2284 static void ccgDM_drawMappedFaces(DerivedMesh *dm, | |
2285 DMSetDrawOptions setDrawOptions, | |
2286 DMSetMaterial setMaterial, | |
2287 DMCompareDrawOptions compareDrawOptions, | |
2288 void *userData, DMDrawFlag flag) | |
2289 { | |
2290 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
2291 CCGSubSurf *ss = ccgdm->ss; | |
2292 CCGKey key; | |
2293 MCol *mcol = NULL; | |
2294 int i, gridSize = ccgSubSurf_getGridSize(ss); | |
2295 DMFlagMat *faceFlags = ccgdm->faceFlags; | |
2296 int useColors = flag & DM_DRAW_USE_COLORS; | |
2297 int gridFaces = gridSize - 1, totface; | |
2298 | |
2299 CCG_key_top_level(&key, ss); | |
2300 | |
2301 /* currently unused -- each original face is handled separately */ | |
2302 (void)compareDrawOptions; | |
2303 | |
2304 if (useColors) { | |
2305 mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); | |
2306 if (!mcol) | |
2307 mcol = dm->getTessFaceDataArray(dm, CD_MCOL); | |
2308 } | |
2309 | |
2310 totface = ccgSubSurf_getNumFaces(ss); | |
2311 for (i = 0; i < totface; i++) { | |
2312 CCGFace *f = ccgdm->faceMap[i].face; | |
2313 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); | |
2314 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); | |
2315 int origIndex; | |
2316 unsigned char *cp = NULL; | |
2317 | |
2318 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)
); | |
2319 | |
2320 if (flag & DM_DRAW_ALWAYS_SMOOTH) drawSmooth = 1; | |
2321 else if (faceFlags) drawSmooth = (faceFlags[origIndex].flag & ME
_SMOOTH); | |
2322 else drawSmooth = 1; | |
2323 | |
2324 if (mcol) { | |
2325 cp = (unsigned char *)mcol; | |
2326 mcol += gridFaces * gridFaces * numVerts * 4; | |
2327 } | |
2328 | |
2329 { | |
2330 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | |
2331 | |
2332 if (index == ORIGINDEX_NONE) | |
2333 draw_option = setMaterial(faceFlags ? faceFlags[
origIndex].mat_nr + 1 : 1, NULL); /* XXX, no faceFlags no material */ | |
2334 else if (setDrawOptions) | |
2335 draw_option = setDrawOptions(userData, index); | |
2336 | |
2337 if (draw_option != DM_DRAW_OPTION_SKIP) { | |
2338 if (draw_option == DM_DRAW_OPTION_STIPPLE) { | |
2339 glEnable(GL_POLYGON_STIPPLE); | |
2340 glPolygonStipple(stipple_quarttone); | |
2341 } | |
2342 | |
2343 /* no need to set shading mode to flat because | |
2344 * normals are already used to change shading *
/ | |
2345 glShadeModel(GL_SMOOTH); | |
2346 ································ | |
2347 for (S=0; S<numVerts; S++) { | |
2348 CCGElem *faceGridData = ccgSubSurf_getFa
ceGridDataArray(ss, f, S); | |
2349 if (drawSmooth) { | |
2350 for (y = 0; y < gridFaces; y++)
{ | |
2351 CCGElem *a, *b; | |
2352 glBegin(GL_QUAD_STRIP); | |
2353 for (x = 0; x < gridFace
s; x++) { | |
2354 a = CCG_grid_ele
m(&key, faceGridData, x, y + 0); | |
2355 b = CCG_grid_ele
m(&key, faceGridData, x, y + 1); | |
2356 ········ | |
2357 if (cp) glColor3
ub(cp[3], cp[2], cp[1]); | |
2358 glNormal3fv(CCG_
elem_no(&key, a)); | |
2359 glVertex3fv(CCG_
elem_co(&key, a)); | |
2360 if (cp) glColor3
ub(cp[7], cp[6], cp[5]); | |
2361 glNormal3fv(CCG_
elem_no(&key, b)); | |
2362 glVertex3fv(CCG_
elem_co(&key, b)); | |
2363 | |
2364 if (x != gridFac
es - 1) { | |
2365 if (cp)
cp += 16; | |
2366 } | |
2367 } | |
2368 | |
2369 a = CCG_grid_elem(&key,
faceGridData, x, y + 0); | |
2370 b = CCG_grid_elem(&key,
faceGridData, x, y + 1); | |
2371 | |
2372 if (cp) glColor3ub(cp[15
], cp[14], cp[13]); | |
2373 glNormal3fv(CCG_elem_no(
&key, a)); | |
2374 glVertex3fv(CCG_elem_co(
&key, a)); | |
2375 if (cp) glColor3ub(cp[11
], cp[10], cp[9]); | |
2376 glNormal3fv(CCG_elem_no(
&key, b)); | |
2377 glVertex3fv(CCG_elem_co(
&key, b)); | |
2378 | |
2379 if (cp) cp += 16; | |
2380 | |
2381 glEnd(); | |
2382 } | |
2383 } | |
2384 else { | |
2385 glBegin(GL_QUADS); | |
2386 for (y = 0; y < gridFaces; y++)
{ | |
2387 for (x = 0; x < gridFace
s; x++) { | |
2388 float *a = CCG_g
rid_elem_co(&key, faceGridData, x, y + 0); | |
2389 float *b = CCG_g
rid_elem_co(&key, faceGridData, x + 1, y + 0); | |
2390 float *c = CCG_g
rid_elem_co(&key, faceGridData, x + 1, y + 1); | |
2391 float *d = CCG_g
rid_elem_co(&key, faceGridData, x, y + 1); | |
2392 | |
2393 ccgDM_glNormalFa
st(a, b, c, d); | |
2394 ········ | |
2395 if (cp) glColor3
ub(cp[7], cp[6], cp[5]); | |
2396 glVertex3fv(d); | |
2397 if (cp) glColor3
ub(cp[11], cp[10], cp[9]); | |
2398 glVertex3fv(c); | |
2399 if (cp) glColor3
ub(cp[15], cp[14], cp[13]); | |
2400 glVertex3fv(b); | |
2401 if (cp) glColor3
ub(cp[3], cp[2], cp[1]); | |
2402 glVertex3fv(a); | |
2403 | |
2404 if (cp) cp += 16
; | |
2405 } | |
2406 } | |
2407 glEnd(); | |
2408 } | |
2409 } | |
2410 if (draw_option == DM_DRAW_OPTION_STIPPLE) | |
2411 glDisable(GL_POLYGON_STIPPLE); | |
2412 } | |
2413 } | |
2414 } | |
2415 } | |
2416 | |
2417 static void ccgDM_drawMappedEdges(DerivedMesh *dm, | |
2418 DMSetDrawOptions setDrawOptions, | |
2419 void *userData) | |
2420 { | |
2421 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
2422 CCGSubSurf *ss = ccgdm->ss; | |
2423 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); | |
2424 CCGKey key; | |
2425 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); | |
2426 | |
2427 CCG_key_top_level(&key, ss); | |
2428 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); | |
2429 | |
2430 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { | |
2431 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); | |
2432 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); | |
2433 int index = ccgDM_getEdgeMapIndex(ss, e); | |
2434 | |
2435 glBegin(GL_LINE_STRIP); | |
2436 if (index != -1 && (!setDrawOptions || (setDrawOptions(userData,
index) != DM_DRAW_OPTION_SKIP))) { | |
2437 if (useAging && !(G.f & G_BACKBUFSEL)) { | |
2438 int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e)
* 4; | |
2439 glColor3ub(0, ageCol > 0 ? ageCol : 0, 0); | |
2440 } | |
2441 | |
2442 for (i = 0; i < edgeSize - 1; i++) { | |
2443 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i
)); | |
2444 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i
+ 1)); | |
2445 } | |
2446 } | |
2447 glEnd(); | |
2448 } | |
2449 | |
2450 ccgEdgeIterator_free(ei); | |
2451 } | |
2452 | |
2453 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, | |
2454 DMSetDrawOptions setDrawOptions, | |
2455 DMSetDrawInterpOptions setDrawInterpOpti
ons, | |
2456 void *userData) | |
2457 { | |
2458 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
2459 CCGSubSurf *ss = ccgdm->ss; | |
2460 CCGKey key; | |
2461 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); | |
2462 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); | |
2463 | |
2464 CCG_key_top_level(&key, ss); | |
2465 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); | |
2466 | |
2467 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { | |
2468 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); | |
2469 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); | |
2470 int index = ccgDM_getEdgeMapIndex(ss, e); | |
2471 | |
2472 glBegin(GL_LINE_STRIP); | |
2473 if (index != -1 && (!setDrawOptions || (setDrawOptions(userData,
index) != DM_DRAW_OPTION_SKIP))) { | |
2474 for (i = 0; i < edgeSize; i++) { | |
2475 setDrawInterpOptions(userData, index, (float) i
/ (edgeSize - 1)); | |
2476 | |
2477 if (useAging && !(G.f & G_BACKBUFSEL)) { | |
2478 int ageCol = 255 - ccgSubSurf_getEdgeAge
(ss, e) * 4; | |
2479 glColor3ub(0, ageCol > 0 ? ageCol : 0, 0
); | |
2480 } | |
2481 | |
2482 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i
)); | |
2483 } | |
2484 } | |
2485 glEnd(); | |
2486 } | |
2487 | |
2488 ccgEdgeIterator_free(ei); | |
2489 } | |
2490 | |
2491 static void ccgDM_foreachMappedFaceCenter( | |
2492 DerivedMesh *dm, | |
2493 void (*func)(void *userData, int index, const float co[3], const float no[3]
), | |
2494 void *userData) | |
2495 { | |
2496 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
2497 CCGSubSurf *ss = ccgdm->ss; | |
2498 CCGKey key; | |
2499 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); | |
2500 | |
2501 CCG_key_top_level(&key, ss); | |
2502 | |
2503 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { | |
2504 CCGFace *f = ccgFaceIterator_getCurrent(fi); | |
2505 int index = ccgDM_getFaceMapIndex(ss, f); | |
2506 | |
2507 if (index != -1) { | |
2508 /* Face center data normal isn't updated atm. */ | |
2509 CCGElem *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0)
; | |
2510 | |
2511 func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no
(&key, vd)); | |
2512 } | |
2513 } | |
2514 | |
2515 ccgFaceIterator_free(fi); | |
2516 } | |
2517 | |
2518 static void ccgDM_release(DerivedMesh *dm) | |
2519 { | |
2520 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; | |
2521 | |
2522 if (DM_release(dm)) { | |
2523 /* Before freeing, need to update the displacement map */ | |
2524 if (ccgdm->multires.modified_flags) { | |
2525 /* Check that mmd still exists */ | |
2526 if (!ccgdm->multires.local_mmd && | |
2527 BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm-
>multires.mmd) < 0) | |
2528 { | |
2529 ccgdm->multires.mmd = NULL; | |
2530 } | |
2531 ························ | |
2532 if (ccgdm->multires.mmd) { | |
2533 if (ccgdm->multires.modified_flags & MULTIRES_CO
ORDS_MODIFIED) | |
2534 multires_modifier_update_mdisps(dm); | |
2535 if (ccgdm->multires.modified_flags & MULTIRES_HI
DDEN_MODIFIED) | |
2536 multires_modifier_update_hidden(dm); | |
2537 } | |
2538 } | |
2539 | |
2540 if (ccgdm->ehash) | |
2541 BLI_edgehash_free(ccgdm->ehash, NULL); | |
2542 | |
2543 if (ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap); | |
2544 if (ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces); | |
2545 if (ccgdm->gridData) MEM_freeN(ccgdm->gridData); | |
2546 if (ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency); | |
2547 if (ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset); | |
2548 if (ccgdm->gridFlagMats) MEM_freeN(ccgdm->gridFlagMats); | |
2549 if (ccgdm->gridHidden) { | |
2550 int i, numGrids = dm->getNumGrids(dm); | |
2551 for (i = 0; i < numGrids; i++) { | |
2552 if (ccgdm->gridHidden[i]) | |
2553 MEM_freeN(ccgdm->gridHidden[i]); | |
2554 } | |
2555 MEM_freeN(ccgdm->gridHidden); | |
2556 } | |
2557 if (ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss); | |
2558 if (ccgdm->pmap) MEM_freeN(ccgdm->pmap); | |
2559 if (ccgdm->pmap_mem) MEM_freeN(ccgdm->pmap_mem); | |
2560 MEM_freeN(ccgdm->edgeFlags); | |
2561 MEM_freeN(ccgdm->faceFlags); | |
2562 MEM_freeN(ccgdm->vertMap); | |
2563 MEM_freeN(ccgdm->edgeMap); | |
2564 MEM_freeN(ccgdm->faceMap); | |
2565 MEM_freeN(ccgdm); | |
2566 } | |
2567 } | |
2568 | |
2569 static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata,· | |
2570 CustomData *pdata, int loopstart, int findex,
int polyindex, | |
2571 const int numTex, const int numCol, const int h
asPCol, const int hasOrigSpace) | |
2572 { | |
2573 MTFace *texface; | |
2574 MTexPoly *texpoly; | |
2575 MCol *mcol; | |
2576 MLoopCol *mloopcol; | |
2577 MLoopUV *mloopuv; | |
2578 int i, j; | |
2579 | |
2580 for (i = 0; i < numTex; i++) { | |
2581 texface = CustomData_get_n(fdata, CD_MTFACE, findex, i); | |
2582 texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i); | |
2583 ················ | |
2584 ME_MTEXFACE_CPY(texface, texpoly); | |
2585 | |
2586 mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i); | |
2587 for (j = 0; j < 4; j++, mloopuv++) { | |
2588 copy_v2_v2(texface->uv[j], mloopuv->uv); | |
2589 } | |
2590 } | |
2591 | |
2592 for (i = 0; i < numCol; i++) { | |
2593 mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i); | |
2594 mcol = CustomData_get_n(fdata, CD_MCOL, findex, i); | |
2595 | |
2596 for (j = 0; j < 4; j++, mloopcol++) { | |
2597 MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]); | |
2598 } | |
2599 } | |
2600 ········ | |
2601 if (hasPCol) { | |
2602 mloopcol = CustomData_get(ldata, loopstart, CD_PREVIEW_MLOOPCOL)
; | |
2603 mcol = CustomData_get(fdata, findex, CD_PREVIEW_MCOL); | |
2604 | |
2605 for (j = 0; j < 4; j++, mloopcol++) { | |
2606 MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]); | |
2607 } | |
2608 } | |
2609 | |
2610 if (hasOrigSpace) { | |
2611 OrigSpaceFace *of = CustomData_get(fdata, findex, CD_ORIGSPACE); | |
2612 OrigSpaceLoop *lof; | |
2613 | |
2614 lof = CustomData_get(ldata, loopstart, CD_ORIGSPACE_MLOOP); | |
2615 for (j = 0; j < 4; j++, lof++) { | |
2616 copy_v2_v2(of->uv[j], lof->uv); | |
2617 } | |
2618 } | |
2619 } | |
2620 | |
2621 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type) | |
2622 { | |
2623 if (type == CD_ORIGINDEX) { | |
2624 /* create origindex on demand to save memory */ | |
2625 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2626 CCGSubSurf *ss = ccgdm->ss; | |
2627 int *origindex; | |
2628 int a, index, totnone, totorig; | |
2629 | |
2630 /* Avoid re-creation if the layer exists already */ | |
2631 origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX); | |
2632 if (origindex) { | |
2633 return origindex; | |
2634 } | |
2635 | |
2636 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); | |
2637 origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX); | |
2638 | |
2639 totorig = ccgSubSurf_getNumVerts(ss); | |
2640 totnone = dm->numVertData - totorig; | |
2641 | |
2642 /* original vertices are at the end */ | |
2643 for (a = 0; a < totnone; a++) | |
2644 origindex[a] = ORIGINDEX_NONE; | |
2645 | |
2646 for (index = 0; index < totorig; index++, a++) { | |
2647 CCGVert *v = ccgdm->vertMap[index].vert; | |
2648 origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v); | |
2649 } | |
2650 | |
2651 return origindex; | |
2652 } | |
2653 | |
2654 return DM_get_vert_data_layer(dm, type); | |
2655 } | |
2656 | |
2657 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type) | |
2658 { | |
2659 if (type == CD_ORIGINDEX) { | |
2660 /* create origindex on demand to save memory */ | |
2661 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2662 CCGSubSurf *ss = ccgdm->ss; | |
2663 int *origindex; | |
2664 int a, i, index, totnone, totorig, totedge; | |
2665 int edgeSize = ccgSubSurf_getEdgeSize(ss); | |
2666 | |
2667 /* Avoid re-creation if the layer exists already */ | |
2668 origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX); | |
2669 if (origindex) { | |
2670 return origindex; | |
2671 } | |
2672 | |
2673 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); | |
2674 origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX); | |
2675 | |
2676 totedge = ccgSubSurf_getNumEdges(ss); | |
2677 totorig = totedge * (edgeSize - 1); | |
2678 totnone = dm->numEdgeData - totorig; | |
2679 | |
2680 /* original edges are at the end */ | |
2681 for (a = 0; a < totnone; a++) | |
2682 origindex[a] = ORIGINDEX_NONE; | |
2683 | |
2684 for (index = 0; index < totedge; index++) { | |
2685 CCGEdge *e = ccgdm->edgeMap[index].edge; | |
2686 int mapIndex = ccgDM_getEdgeMapIndex(ss, e); | |
2687 | |
2688 for (i = 0; i < edgeSize - 1; i++, a++) | |
2689 origindex[a] = mapIndex; | |
2690 } | |
2691 | |
2692 return origindex; | |
2693 } | |
2694 | |
2695 return DM_get_edge_data_layer(dm, type); | |
2696 } | |
2697 | |
2698 static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type) | |
2699 { | |
2700 if (type == CD_ORIGINDEX) { | |
2701 /* create origindex on demand to save memory */ | |
2702 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2703 CCGSubSurf *ss = ccgdm->ss; | |
2704 int *origindex; | |
2705 int a, i, index, totface; | |
2706 int gridFaces = ccgSubSurf_getGridSize(ss) - 1; | |
2707 | |
2708 /* Avoid re-creation if the layer exists already */ | |
2709 origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); | |
2710 if (origindex) { | |
2711 return origindex; | |
2712 } | |
2713 | |
2714 DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); | |
2715 origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); | |
2716 | |
2717 totface = ccgSubSurf_getNumFaces(ss); | |
2718 | |
2719 for (a = 0, index = 0; index < totface; index++) { | |
2720 CCGFace *f = ccgdm->faceMap[index].face; | |
2721 int numVerts = ccgSubSurf_getFaceNumVerts(f); | |
2722 int mapIndex = ccgDM_getFaceMapIndex(ss, f); | |
2723 | |
2724 for (i = 0; i < gridFaces * gridFaces * numVerts; i++, a
++) | |
2725 origindex[a] = mapIndex; | |
2726 } | |
2727 | |
2728 return origindex; | |
2729 } | |
2730 | |
2731 return DM_get_tessface_data_layer(dm, type); | |
2732 } | |
2733 | |
2734 static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type) | |
2735 { | |
2736 if (type == CD_ORIGINDEX) { | |
2737 /* ensure creation of CD_ORIGINDEX layer */ | |
2738 ccgDM_get_vert_data_layer(dm, type); | |
2739 } | |
2740 | |
2741 return DM_get_vert_data(dm, index, type); | |
2742 } | |
2743 | |
2744 static void *ccgDM_get_edge_data(DerivedMesh *dm, int index, int type) | |
2745 { | |
2746 if (type == CD_ORIGINDEX) { | |
2747 /* ensure creation of CD_ORIGINDEX layer */ | |
2748 ccgDM_get_edge_data_layer(dm, type); | |
2749 } | |
2750 | |
2751 return DM_get_edge_data(dm, index, type); | |
2752 } | |
2753 | |
2754 static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type) | |
2755 { | |
2756 if (type == CD_ORIGINDEX) { | |
2757 /* ensure creation of CD_ORIGINDEX layer */ | |
2758 ccgDM_get_tessface_data_layer(dm, type); | |
2759 } | |
2760 | |
2761 return DM_get_tessface_data(dm, index, type); | |
2762 } | |
2763 | |
2764 static int ccgDM_getNumGrids(DerivedMesh *dm) | |
2765 { | |
2766 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2767 int index, numFaces, numGrids; | |
2768 | |
2769 numFaces = ccgSubSurf_getNumFaces(ccgdm->ss); | |
2770 numGrids = 0; | |
2771 | |
2772 for (index = 0; index < numFaces; index++) { | |
2773 CCGFace *f = ccgdm->faceMap[index].face; | |
2774 numGrids += ccgSubSurf_getFaceNumVerts(f); | |
2775 } | |
2776 | |
2777 return numGrids; | |
2778 } | |
2779 | |
2780 static int ccgDM_getGridSize(DerivedMesh *dm) | |
2781 { | |
2782 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2783 return ccgSubSurf_getGridSize(ccgdm->ss); | |
2784 } | |
2785 | |
2786 static int ccgdm_adjacent_grid(int *gridOffset, CCGFace *f, int S, int offset) | |
2787 { | |
2788 CCGFace *adjf; | |
2789 CCGEdge *e; | |
2790 int i, j = 0, numFaces, fIndex, numEdges = 0; | |
2791 | |
2792 e = ccgSubSurf_getFaceEdge(f, S); | |
2793 numFaces = ccgSubSurf_getEdgeNumFaces(e); | |
2794 | |
2795 if (numFaces != 2) | |
2796 return -1; | |
2797 | |
2798 for (i = 0; i < numFaces; i++) { | |
2799 adjf = ccgSubSurf_getEdgeFace(e, i); | |
2800 | |
2801 if (adjf != f) { | |
2802 numEdges = ccgSubSurf_getFaceNumVerts(adjf); | |
2803 for (j = 0; j < numEdges; j++) | |
2804 if (ccgSubSurf_getFaceEdge(adjf, j) == e) | |
2805 break; | |
2806 | |
2807 if (j != numEdges) | |
2808 break; | |
2809 } | |
2810 } | |
2811 | |
2812 if (numEdges == 0) | |
2813 return -1; | |
2814 ········ | |
2815 fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(adjf)); | |
2816 | |
2817 return gridOffset[fIndex] + (j + offset) % numEdges; | |
2818 } | |
2819 | |
2820 static void ccgdm_create_grids(DerivedMesh *dm) | |
2821 { | |
2822 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2823 CCGSubSurf *ss = ccgdm->ss; | |
2824 CCGElem **gridData; | |
2825 DMGridAdjacency *gridAdjacency, *adj; | |
2826 DMFlagMat *gridFlagMats; | |
2827 CCGFace **gridFaces; | |
2828 int *gridOffset; | |
2829 int index, numFaces, numGrids, S, gIndex /*, gridSize*/; | |
2830 | |
2831 if (ccgdm->gridData) | |
2832 return; | |
2833 ········ | |
2834 numGrids = ccgDM_getNumGrids(dm); | |
2835 numFaces = ccgSubSurf_getNumFaces(ss); | |
2836 /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/ | |
2837 | |
2838 /* compute offset into grid array for each face */ | |
2839 gridOffset = MEM_mallocN(sizeof(int) * numFaces, "ccgdm.gridOffset"); | |
2840 | |
2841 for (gIndex = 0, index = 0; index < numFaces; index++) { | |
2842 CCGFace *f = ccgdm->faceMap[index].face; | |
2843 int numVerts = ccgSubSurf_getFaceNumVerts(f); | |
2844 | |
2845 gridOffset[index] = gIndex; | |
2846 gIndex += numVerts; | |
2847 } | |
2848 | |
2849 /* compute grid data */ | |
2850 gridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData"); | |
2851 gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency) * numGrids, "ccgdm.g
ridAdjacency"); | |
2852 gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces")
; | |
2853 gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlag
Mats"); | |
2854 | |
2855 ccgdm->gridHidden = MEM_callocN(sizeof(BLI_bitmap) * numGrids, "ccgdm.gr
idHidden"); | |
2856 | |
2857 for (gIndex = 0, index = 0; index < numFaces; index++) { | |
2858 CCGFace *f = ccgdm->faceMap[index].face; | |
2859 int numVerts = ccgSubSurf_getFaceNumVerts(f); | |
2860 | |
2861 for (S = 0; S < numVerts; S++, gIndex++) { | |
2862 int prevS = (S - 1 + numVerts) % numVerts; | |
2863 int nextS = (S + 1 + numVerts) % numVerts; | |
2864 | |
2865 gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f
, S); | |
2866 gridFaces[gIndex] = f; | |
2867 gridFlagMats[gIndex] = ccgdm->faceFlags[index]; | |
2868 | |
2869 adj = &gridAdjacency[gIndex]; | |
2870 | |
2871 adj->index[0] = gIndex - S + nextS; | |
2872 adj->rotation[0] = 3; | |
2873 adj->index[1] = ccgdm_adjacent_grid(gridOffset, f, prevS
, 0); | |
2874 adj->rotation[1] = 1; | |
2875 adj->index[2] = ccgdm_adjacent_grid(gridOffset, f, S, 1)
; | |
2876 adj->rotation[2] = 3; | |
2877 adj->index[3] = gIndex - S + prevS; | |
2878 adj->rotation[3] = 1; | |
2879 } | |
2880 } | |
2881 | |
2882 ccgdm->gridData = gridData; | |
2883 ccgdm->gridFaces = gridFaces; | |
2884 ccgdm->gridAdjacency = gridAdjacency; | |
2885 ccgdm->gridOffset = gridOffset; | |
2886 ccgdm->gridFlagMats = gridFlagMats; | |
2887 } | |
2888 | |
2889 static CCGElem **ccgDM_getGridData(DerivedMesh *dm) | |
2890 { | |
2891 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2892 | |
2893 ccgdm_create_grids(dm); | |
2894 return ccgdm->gridData; | |
2895 } | |
2896 | |
2897 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm) | |
2898 { | |
2899 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2900 | |
2901 ccgdm_create_grids(dm); | |
2902 return ccgdm->gridAdjacency; | |
2903 } | |
2904 | |
2905 static int *ccgDM_getGridOffset(DerivedMesh *dm) | |
2906 { | |
2907 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2908 | |
2909 ccgdm_create_grids(dm); | |
2910 return ccgdm->gridOffset; | |
2911 } | |
2912 | |
2913 static void ccgDM_getGridKey(DerivedMesh *dm, CCGKey *key) | |
2914 { | |
2915 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; | |
2916 CCG_key_top_level(key, ccgdm->ss); | |
2917 } | |
2918 | |
2919 static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm) | |
2920 { | |
2921 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2922 ········ | |
2923 ccgdm_create_grids(dm); | |
2924 return ccgdm->gridFlagMats; | |
2925 } | |
2926 | |
2927 static BLI_bitmap *ccgDM_getGridHidden(DerivedMesh *dm) | |
2928 { | |
2929 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2930 ········ | |
2931 ccgdm_create_grids(dm); | |
2932 return ccgdm->gridHidden; | |
2933 } | |
2934 | |
2935 static const MeshElemMap *ccgDM_getPolyMap(Object *ob, DerivedMesh *dm) | |
2936 { | |
2937 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2938 | |
2939 if (!ccgdm->multires.mmd && !ccgdm->pmap && ob->type == OB_MESH) { | |
2940 Mesh *me = ob->data; | |
2941 | |
2942 create_vert_poly_map(&ccgdm->pmap, &ccgdm->pmap_mem, | |
2943 me->mpoly, me->mloop, | |
2944 me->totvert, me->totpoly, me->totloop); | |
2945 } | |
2946 | |
2947 return ccgdm->pmap; | |
2948 } | |
2949 | |
2950 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm) | |
2951 { | |
2952 MultiresModifierData *mmd = ccgdm->multires.mmd; | |
2953 | |
2954 /* both of multires and subsurf modifiers are CCG, but | |
2955 * grids should only be used when sculpting on multires */ | |
2956 if (!mmd) | |
2957 return 0; | |
2958 | |
2959 return 1; | |
2960 } | |
2961 | |
2962 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) | |
2963 { | |
2964 CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; | |
2965 CCGKey key; | |
2966 int numGrids, grid_pbvh; | |
2967 | |
2968 CCG_key_top_level(&key, ccgdm->ss); | |
2969 | |
2970 if (!ob) { | |
2971 ccgdm->pbvh = NULL; | |
2972 return NULL; | |
2973 } | |
2974 | |
2975 if (!ob->sculpt) | |
2976 return NULL; | |
2977 | |
2978 grid_pbvh = ccgDM_use_grid_pbvh(ccgdm); | |
2979 | |
2980 if (ob->sculpt->pbvh) { | |
2981 if (grid_pbvh) { | |
2982 /* pbvh's grids, gridadj and gridfaces points to data in
side ccgdm | |
2983 * but this can be freed on ccgdm release, this updates
the pointers | |
2984 * when the ccgdm gets remade, the assumption is that th
e topology | |
2985 * does not change. */ | |
2986 ccgdm_create_grids(dm); | |
2987 BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData,
ccgdm->gridAdjacency, (void **)ccgdm->gridFaces); | |
2988 } | |
2989 | |
2990 ccgdm->pbvh = ob->sculpt->pbvh; | |
2991 } | |
2992 | |
2993 if (ccgdm->pbvh) | |
2994 return ccgdm->pbvh; | |
2995 | |
2996 /* no pbvh exists yet, we need to create one. only in case of multires | |
2997 * we build a pbvh over the modified mesh, in other cases the base mesh | |
2998 * is being sculpted, so we build a pbvh from that. */ | |
2999 if (grid_pbvh) { | |
3000 ccgdm_create_grids(dm); | |
3001 | |
3002 numGrids = ccgDM_getNumGrids(dm); | |
3003 | |
3004 ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new(); | |
3005 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAd
jacency, | |
3006 numGrids, &key, (void *
*) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden); | |
3007 } | |
3008 else if(ob->type == OB_MESH) { | |
3009 Mesh *me= ob->data; | |
3010 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); | |
3011 BLI_assert(!(me->mface == NULL && me->mpoly != NULL)); /* BMESH
ONLY complain if mpoly is valid but not mface */ | |
3012 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert, | |
3013 me->totface, me->totvert
, &me->vdata); | |
3014 } | |
3015 | |
3016 return ccgdm->pbvh; | |
3017 } | |
3018 | |
3019 static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm)) | |
3020 { | |
3021 /* Nothing to do: CCG handles creating its own tessfaces */ | |
3022 } | |
3023 | |
3024 static void ccgDM_calcNormals(DerivedMesh *UNUSED(dm)) | |
3025 { | |
3026 /* Nothing to do: CCG calculates normals during drawing */ | |
3027 } | |
3028 | |
3029 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, | |
3030 int drawInteriorEdges, | |
3031 int useSubsurfUv, | |
3032 DerivedMesh *dm) | |
3033 { | |
3034 CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm"); | |
3035 CCGVertIterator *vi; | |
3036 CCGEdgeIterator *ei; | |
3037 CCGFaceIterator *fi; | |
3038 int index, totvert, totedge, totface; | |
3039 int i; | |
3040 int vertNum, edgeNum, faceNum; | |
3041 int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex;
/* *edgeOrigIndex - as yet, unused */ | |
3042 short *edgeFlags; | |
3043 DMFlagMat *faceFlags; | |
3044 int *loopidx = NULL, *vertidx = NULL, *polyidx = NULL; | |
3045 BLI_array_declare(loopidx); | |
3046 BLI_array_declare(vertidx); | |
3047 int loopindex, loopindex2; | |
3048 int edgeSize, has_edge_origindex; | |
3049 int gridSize; | |
3050 int gridFaces, gridCuts; | |
3051 /*int gridSideVerts;*/ | |
3052 int gridSideEdges; | |
3053 int numTex, numCol; | |
3054 int hasPCol, hasOrigSpace; | |
3055 int gridInternalEdges; | |
3056 float *w = NULL; | |
3057 WeightTable wtable = {0}; | |
3058 /* MCol *mcol; */ /* UNUSED */ | |
3059 MEdge *medge = NULL; | |
3060 /* MFace *mface = NULL; */ | |
3061 MPoly *mpoly = NULL; | |
3062 | |
3063 DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM, | |
3064 ccgSubSurf_getNumFinalVerts(ss), | |
3065 ccgSubSurf_getNumFinalEdges(ss), | |
3066 ccgSubSurf_getNumFinalFaces(ss), | |
3067 ccgSubSurf_getNumFinalFaces(ss) * 4, | |
3068 ccgSubSurf_getNumFinalFaces(ss)); | |
3069 | |
3070 CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL, | |
3071 ccgdm->dm.numPolyData); | |
3072 ········ | |
3073 numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV); | |
3074 numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL); | |
3075 hasPCol = CustomData_has_layer(&ccgdm->dm.loopData, CD_PREVIEW_MLOOPCOL)
; | |
3076 hasOrigSpace = CustomData_has_layer(&ccgdm->dm.loopData, CD_ORIGSPACE_ML
OOP); | |
3077 ········ | |
3078 if ( | |
3079 (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFAC
E) != numTex) || | |
3080 (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL)
!= numCol) || | |
3081 (hasPCol && !CustomData_has_layer(&ccgdm->dm.faceData, CD_PREVIEW_MC
OL)) || | |
3082 (hasOrigSpace && !CustomData_has_layer(&ccgdm->dm.faceData, CD_ORIGS
PACE)) ) | |
3083 { | |
3084 CustomData_from_bmeshpoly(&ccgdm->dm.faceData, | |
3085 &ccgdm->dm.polyData, | |
3086 &ccgdm->dm.loopData, | |
3087 ccgSubSurf_getNumFinalFaces(ss)); | |
3088 } | |
3089 | |
3090 /* We absolutely need that layer, else it's no valid tessellated data! *
/ | |
3091 polyidx = CustomData_add_layer(&ccgdm->dm.faceData, CD_POLYINDEX, CD_CAL
LOC, | |
3092 NULL, ccgSubSurf_getNumFinalFaces(ss)); | |
3093 | |
3094 ccgdm->dm.getMinMax = ccgDM_getMinMax; | |
3095 ccgdm->dm.getNumVerts = ccgDM_getNumVerts; | |
3096 ccgdm->dm.getNumEdges = ccgDM_getNumEdges; | |
3097 ccgdm->dm.getNumTessFaces = ccgDM_getNumTessFaces; | |
3098 ccgdm->dm.getNumLoops = ccgDM_getNumLoops; | |
3099 /* reuse of ccgDM_getNumTessFaces is intentional here: subsurf polys are
just created from tessfaces */ | |
3100 ccgdm->dm.getNumPolys = ccgDM_getNumTessFaces; | |
3101 | |
3102 ccgdm->dm.getNumGrids = ccgDM_getNumGrids; | |
3103 ccgdm->dm.getPBVH = ccgDM_getPBVH; | |
3104 | |
3105 ccgdm->dm.getVert = ccgDM_getFinalVert; | |
3106 ccgdm->dm.getEdge = ccgDM_getFinalEdge; | |
3107 ccgdm->dm.getTessFace = ccgDM_getFinalFace; | |
3108 ccgdm->dm.getVertCo = ccgDM_getFinalVertCo; | |
3109 ccgdm->dm.getVertNo = ccgDM_getFinalVertNo; | |
3110 ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray; | |
3111 ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray; | |
3112 ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray; | |
3113 ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray; | |
3114 ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray; | |
3115 | |
3116 ccgdm->dm.getVertData = ccgDM_get_vert_data; | |
3117 ccgdm->dm.getEdgeData = ccgDM_get_edge_data; | |
3118 ccgdm->dm.getTessFaceData = ccgDM_get_tessface_data; | |
3119 ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer; | |
3120 ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer; | |
3121 ccgdm->dm.getTessFaceDataArray = ccgDM_get_tessface_data_layer; | |
3122 ccgdm->dm.getNumGrids = ccgDM_getNumGrids; | |
3123 ccgdm->dm.getGridSize = ccgDM_getGridSize; | |
3124 ccgdm->dm.getGridData = ccgDM_getGridData; | |
3125 ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency; | |
3126 ccgdm->dm.getGridOffset = ccgDM_getGridOffset; | |
3127 ccgdm->dm.getGridKey = ccgDM_getGridKey; | |
3128 ccgdm->dm.getGridFlagMats = ccgDM_getGridFlagMats; | |
3129 ccgdm->dm.getGridHidden = ccgDM_getGridHidden; | |
3130 ccgdm->dm.getPolyMap = ccgDM_getPolyMap; | |
3131 ccgdm->dm.getPBVH = ccgDM_getPBVH; | |
3132 | |
3133 ccgdm->dm.getTessFace = ccgDM_getFinalFace; | |
3134 ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray; | |
3135 ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray; | |
3136 ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray; | |
3137 | |
3138 ccgdm->dm.calcNormals = ccgDM_calcNormals; | |
3139 ccgdm->dm.recalcTessellation = ccgDM_recalcTessellation; | |
3140 | |
3141 ccgdm->dm.getVertCos = ccgdm_getVertCos; | |
3142 ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert; | |
3143 ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge; | |
3144 ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter; | |
3145 ········ | |
3146 ccgdm->dm.drawVerts = ccgDM_drawVerts; | |
3147 ccgdm->dm.drawEdges = ccgDM_drawEdges; | |
3148 ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges; | |
3149 ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid; | |
3150 ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex; | |
3151 ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL; | |
3152 ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces; | |
3153 ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex; | |
3154 ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL; | |
3155 ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat; | |
3156 ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges; | |
3157 | |
3158 ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp; | |
3159 ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges; | |
3160 ········ | |
3161 ccgdm->dm.release = ccgDM_release; | |
3162 ········ | |
3163 ccgdm->ss = ss; | |
3164 ccgdm->drawInteriorEdges = drawInteriorEdges; | |
3165 ccgdm->useSubsurfUv = useSubsurfUv; | |
3166 | |
3167 totvert = ccgSubSurf_getNumVerts(ss); | |
3168 ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap
"); | |
3169 vi = ccgSubSurf_getVertIterator(ss); | |
3170 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { | |
3171 CCGVert *v = ccgVertIterator_getCurrent(vi); | |
3172 | |
3173 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle
(v))].vert = v; | |
3174 } | |
3175 ccgVertIterator_free(vi); | |
3176 | |
3177 totedge = ccgSubSurf_getNumEdges(ss); | |
3178 ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap
"); | |
3179 ei = ccgSubSurf_getEdgeIterator(ss); | |
3180 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { | |
3181 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); | |
3182 | |
3183 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle
(e))].edge = e; | |
3184 } | |
3185 | |
3186 totface = ccgSubSurf_getNumFaces(ss); | |
3187 ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap
"); | |
3188 fi = ccgSubSurf_getFaceIterator(ss); | |
3189 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { | |
3190 CCGFace *f = ccgFaceIterator_getCurrent(fi); | |
3191 | |
3192 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle
(f))].face = f; | |
3193 } | |
3194 ccgFaceIterator_free(fi); | |
3195 | |
3196 ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinal
Faces(ss), "reverseFaceMap"); | |
3197 | |
3198 edgeSize = ccgSubSurf_getEdgeSize(ss); | |
3199 gridSize = ccgSubSurf_getGridSize(ss); | |
3200 gridFaces = gridSize - 1; | |
3201 gridCuts = gridSize - 2; | |
3202 /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */ | |
3203 gridSideEdges = gridSize - 1; | |
3204 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;· | |
3205 | |
3206 vertNum = 0; | |
3207 edgeNum = 0; | |
3208 faceNum = 0; | |
3209 | |
3210 /* mvert = dm->getVertArray(dm); */ /* UNUSED */ | |
3211 medge = dm->getEdgeArray(dm); | |
3212 /* mface = dm->getTessFaceArray(dm); */ /* UNUSED */ | |
3213 | |
3214 mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); | |
3215 base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX); | |
3216 ········ | |
3217 /*CDDM hack*/ | |
3218 edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short) * totedge, "edg
eFlags"); | |
3219 faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface,
"faceFlags"); | |
3220 | |
3221 vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX); | |
3222 /*edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);*/ | |
3223 faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX); | |
3224 | |
3225 polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX); | |
3226 | |
3227 #if 0 | |
3228 /* this is not in trunk, can gives problems because colors initialize | |
3229 * as black, just don't do it!, it works fine - campbell */ | |
3230 if (!CustomData_has_layer(&ccgdm->dm.faceData, CD_MCOL)) | |
3231 DM_add_tessface_layer(&ccgdm->dm, CD_MCOL, CD_CALLOC, NULL); | |
3232 mcol = DM_get_tessface_data_layer(&ccgdm->dm, CD_MCOL); | |
3233 #endif | |
3234 | |
3235 has_edge_origindex = CustomData_has_layer(&ccgdm->dm.edgeData, CD_ORIGIN
DEX); | |
3236 | |
3237 | |
3238 loopindex = loopindex2 = 0; //current loop index | |
3239 for (index = 0; index < totface; index++) { | |
3240 CCGFace *f = ccgdm->faceMap[index].face; | |
3241 int numVerts = ccgSubSurf_getFaceNumVerts(f); | |
3242 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdge
s); | |
3243 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandl
e(f)); | |
3244 int g2_wid = gridCuts + 2; | |
3245 float *w2; | |
3246 int s, x, y; | |
3247 ················ | |
3248 w = get_ss_weights(&wtable, gridCuts, numVerts); | |
3249 | |
3250 ccgdm->faceMap[index].startVert = vertNum; | |
3251 ccgdm->faceMap[index].startEdge = edgeNum; | |
3252 ccgdm->faceMap[index].startFace = faceNum; | |
3253 ················ | |
3254 faceFlags->flag = mpoly ? mpoly[origIndex].flag : 0; | |
3255 faceFlags->mat_nr = mpoly ? mpoly[origIndex].mat_nr : 0; | |
3256 faceFlags++; | |
3257 | |
3258 origIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] :
origIndex; | |
3259 | |
3260 /* set the face base vert */ | |
3261 *((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum; | |
3262 | |
3263 BLI_array_empty(loopidx); | |
3264 BLI_array_grow_items(loopidx, numVerts); | |
3265 for (s = 0; s < numVerts; s++) { | |
3266 loopidx[s] = loopindex++; | |
3267 } | |
3268 ················ | |
3269 BLI_array_empty(vertidx); | |
3270 BLI_array_grow_items(vertidx, numVerts); | |
3271 for (s = 0; s < numVerts; s++) { | |
3272 CCGVert *v = ccgSubSurf_getFaceVert(f, s); | |
3273 vertidx[s] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVert
Handle(v)); | |
3274 } | |
3275 ················ | |
3276 | |
3277 /*I think this is for interpolating the center vert?*/ | |
3278 w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid
-1)*g2_wid+g2_wid-1); | |
3279 DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, | |
3280 numVerts, vertNum); | |
3281 if (vertOrigIndex) { | |
3282 *vertOrigIndex = ORIGINDEX_NONE; | |
3283 ++vertOrigIndex; | |
3284 } | |
3285 | |
3286 ++vertNum; | |
3287 | |
3288 /*interpolate per-vert data*/ | |
3289 for (s = 0; s < numVerts; s++) { | |
3290 for (x = 1; x < gridFaces; x++) { | |
3291 w2 = w + s * numVerts * g2_wid * g2_wid + x * nu
mVerts; | |
3292 DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, | |
3293 numVerts, vertNum); | |
3294 | |
3295 if (vertOrigIndex) { | |
3296 *vertOrigIndex = ORIGINDEX_NONE; | |
3297 ++vertOrigIndex; | |
3298 } | |
3299 | |
3300 ++vertNum; | |
3301 } | |
3302 } | |
3303 | |
3304 /*interpolate per-vert data*/ | |
3305 for (s = 0; s < numVerts; s++) { | |
3306 for (y = 1; y < gridFaces; y++) { | |
3307 for (x = 1; x < gridFaces; x++) { | |
3308 w2 = w + s * numVerts * g2_wid * g2_wid
+ (y * g2_wid + x) * numVerts; | |
3309 DM_interp_vert_data(dm, &ccgdm->dm, vert
idx, w2, | |
3310 numVerts, vertNum); | |
3311 | |
3312 if (vertOrigIndex) { | |
3313 *vertOrigIndex = ORIGINDEX_NONE; | |
3314 ++vertOrigIndex; | |
3315 } | |
3316 | |
3317 ++vertNum; | |
3318 } | |
3319 } | |
3320 } | |
3321 | |
3322 if (has_edge_origindex) { | |
3323 for (i = 0; i < numFinalEdges; ++i) | |
3324 *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i
, | |
3325 CD_ORIGINDEX) = ORIGIND
EX_NONE; | |
3326 } | |
3327 | |
3328 for (s = 0; s < numVerts; s++) { | |
3329 /*interpolate per-face data*/ | |
3330 for (y = 0; y < gridFaces; y++) { | |
3331 for (x = 0; x < gridFaces; x++) { | |
3332 w2 = w + s * numVerts * g2_wid * g2_wid
+ (y * g2_wid + x) * numVerts; | |
3333 CustomData_interp(&dm->loopData, &ccgdm-
>dm.loopData, | |
3334 loopidx, w2, NULL, num
Verts, loopindex2); | |
3335 loopindex2++; | |
3336 | |
3337 w2 = w + s * numVerts * g2_wid * g2_wid
+ ((y + 1) * g2_wid + (x)) * numVerts; | |
3338 CustomData_interp(&dm->loopData, &ccgdm-
>dm.loopData, | |
3339 loopidx, w2, NULL, num
Verts, loopindex2); | |
3340 loopindex2++; | |
3341 | |
3342 w2 = w + s * numVerts * g2_wid * g2_wid
+ ((y + 1) * g2_wid + (x + 1)) * numVerts; | |
3343 CustomData_interp(&dm->loopData, &ccgdm-
>dm.loopData, | |
3344 loopidx, w2, NULL, num
Verts, loopindex2); | |
3345 loopindex2++; | |
3346 ········································ | |
3347 w2 = w + s * numVerts * g2_wid * g2_wid
+ ((y) * g2_wid + (x + 1)) * numVerts; | |
3348 CustomData_interp(&dm->loopData, &ccgdm-
>dm.loopData, | |
3349 loopidx, w2, NULL, num
Verts, loopindex2); | |
3350 loopindex2++; | |
3351 | |
3352 /*copy over poly data, e.g. mtexpoly*/ | |
3353 CustomData_copy_data(&dm->polyData, &ccg
dm->dm.polyData, origIndex, faceNum, 1); | |
3354 | |
3355 /*generate tessellated face data used fo
r drawing*/ | |
3356 ccg_loops_to_corners(&ccgdm->dm.faceData
, &ccgdm->dm.loopData, | |
3357 &ccgdm->dm.polyData
, loopindex2 - 4, faceNum, faceNum, | |
3358 numTex, numCol, has
PCol, hasOrigSpace); | |
3359 ········································ | |
3360 /*set original index data*/ | |
3361 if (faceOrigIndex) { | |
3362 *faceOrigIndex = origIndex; | |
3363 faceOrigIndex++; | |
3364 } | |
3365 if (polyOrigIndex) { | |
3366 *polyOrigIndex = origIndex; | |
3367 polyOrigIndex++; | |
3368 } | |
3369 | |
3370 ccgdm->reverseFaceMap[faceNum] = index; | |
3371 | |
3372 /* This is a simple one to one mapping,
here... */ | |
3373 polyidx[faceNum] = faceNum; | |
3374 | |
3375 faceNum++; | |
3376 } | |
3377 } | |
3378 } | |
3379 | |
3380 edgeNum += numFinalEdges; | |
3381 } | |
3382 | |
3383 for (index = 0; index < totedge; ++index) { | |
3384 CCGEdge *e = ccgdm->edgeMap[index].edge; | |
3385 int numFinalEdges = edgeSize - 1; | |
3386 int mapIndex = ccgDM_getEdgeMapIndex(ss, e); | |
3387 int x; | |
3388 int vertIdx[2]; | |
3389 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(
e)); | |
3390 | |
3391 CCGVert *v; | |
3392 v = ccgSubSurf_getEdgeVert0(e); | |
3393 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v
)); | |
3394 v = ccgSubSurf_getEdgeVert1(e); | |
3395 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v
)); | |
3396 | |
3397 ccgdm->edgeMap[index].startVert = vertNum; | |
3398 ccgdm->edgeMap[index].startEdge = edgeNum; | |
3399 | |
3400 if (edgeIdx >= 0 && edgeFlags) | |
3401 edgeFlags[edgeIdx] = medge[edgeIdx].flag; | |
3402 | |
3403 /* set the edge base vert */ | |
3404 *((int *)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum; | |
3405 | |
3406 for (x = 1; x < edgeSize - 1; x++) { | |
3407 float w[2]; | |
3408 w[1] = (float) x / (edgeSize - 1); | |
3409 w[0] = 1 - w[1]; | |
3410 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertN
um); | |
3411 if (vertOrigIndex) { | |
3412 *vertOrigIndex = ORIGINDEX_NONE; | |
3413 ++vertOrigIndex; | |
3414 } | |
3415 ++vertNum; | |
3416 } | |
3417 | |
3418 for (i = 0; i < numFinalEdges; ++i) { | |
3419 if (has_edge_origindex) { | |
3420 *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i
, CD_ORIGINDEX) = mapIndex; | |
3421 } | |
3422 } | |
3423 | |
3424 edgeNum += numFinalEdges; | |
3425 } | |
3426 | |
3427 if (useSubsurfUv) { | |
3428 CustomData *ldata = &ccgdm->dm.loopData; | |
3429 CustomData *dmldata = &dm->loopData; | |
3430 int numlayer = CustomData_number_of_layers(ldata, CD_MLOOPUV); | |
3431 int dmnumlayer = CustomData_number_of_layers(dmldata, CD_MLOOPUV
); | |
3432 | |
3433 for (i = 0; i < numlayer && i < dmnumlayer; i++) | |
3434 set_subsurf_uv(ss, dm, &ccgdm->dm, i); | |
3435 } | |
3436 | |
3437 for (index = 0; index < totvert; ++index) { | |
3438 CCGVert *v = ccgdm->vertMap[index].vert; | |
3439 int mapIndex = ccgDM_getVertMapIndex(ccgdm->ss, v); | |
3440 int vertIdx; | |
3441 | |
3442 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); | |
3443 | |
3444 ccgdm->vertMap[index].startVert = vertNum; | |
3445 | |
3446 /* set the vert base vert */ | |
3447 *((int *) ccgSubSurf_getVertUserData(ss, v)) = vertNum; | |
3448 | |
3449 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1); | |
3450 | |
3451 if (vertOrigIndex) { | |
3452 *vertOrigIndex = mapIndex; | |
3453 ++vertOrigIndex; | |
3454 } | |
3455 ++vertNum; | |
3456 } | |
3457 | |
3458 ccgdm->dm.numVertData = vertNum; | |
3459 ccgdm->dm.numEdgeData = edgeNum; | |
3460 ccgdm->dm.numTessFaceData = faceNum; | |
3461 ccgdm->dm.numLoopData = loopindex2; | |
3462 ccgdm->dm.numPolyData = faceNum; | |
3463 | |
3464 /* All tessellated CD layers were updated! */ | |
3465 ccgdm->dm.dirty &= ~DM_DIRTY_TESS_CDLAYERS; | |
3466 | |
3467 BLI_array_free(vertidx); | |
3468 BLI_array_free(loopidx); | |
3469 free_ss_weights(&wtable); | |
3470 | |
3471 return ccgdm; | |
3472 } | |
3473 | |
3474 /***/ | |
3475 | |
3476 struct DerivedMesh *subsurf_make_derived_from_derived( | |
3477 struct DerivedMesh *dm, | |
3478 struct SubsurfModifierData *smd, | |
3479 float (*vertCos)[3], | |
3480 SubsurfFlags flags) | |
3481 { | |
3482 int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF; | |
3483 CCGFlags useAging = smd->flags & eSubsurfModifierFlag_DebugIncr ? CCG_US
E_AGING : 0; | |
3484 int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv; | |
3485 int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges
); | |
3486 CCGDerivedMesh *result; | |
3487 | |
3488 if (flags & SUBSURF_FOR_EDIT_MODE) { | |
3489 int levels = (smd->modifier.scene) ? get_render_subsurf_level(&s
md->modifier.scene->r, smd->levels) : smd->levels; | |
3490 | |
3491 smd->emCache = _getSubSurf(smd->emCache, levels, 3, useAging | C
CG_CALC_NORMALS); | |
3492 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple); | |
3493 | |
3494 result = getCCGDerivedMesh(smd->emCache, | |
3495 drawInteriorEdges, | |
3496 useSubsurfUv, dm); | |
3497 } | |
3498 else if (flags & SUBSURF_USE_RENDER_PARAMS) { | |
3499 /* Do not use cache in render mode. */ | |
3500 CCGSubSurf *ss; | |
3501 int levels = (smd->modifier.scene) ? get_render_subsurf_level(&s
md->modifier.scene->r, smd->renderLevels) : smd->renderLevels; | |
3502 | |
3503 if (levels == 0) | |
3504 return dm; | |
3505 ················ | |
3506 ss = _getSubSurf(NULL, levels, 3, CCG_USE_ARENA | CCG_CALC_NORMA
LS); | |
3507 | |
3508 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); | |
3509 | |
3510 result = getCCGDerivedMesh(ss, | |
3511 drawInteriorEdges, useSubsurfUv, dm); | |
3512 | |
3513 result->freeSS = 1; | |
3514 } | |
3515 else { | |
3516 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremen
tal); | |
3517 int levels = (smd->modifier.scene) ? get_render_subsurf_level(&s
md->modifier.scene->r, smd->levels) : smd->levels; | |
3518 CCGSubSurf *ss; | |
3519 | |
3520 /* It is quite possible there is a much better place to do this.
It | |
3521 * depends a bit on how rigorously we expect this function to ne
ver | |
3522 * be called in editmode. In semi-theory we could share a single | |
3523 * cache, but the handles used inside and outside editmode are n
ot | |
3524 * the same so we would need some way of converting them. Its pr
obably | |
3525 * not worth the effort. But then why am I even writing this lon
g | |
3526 * comment that no one will read? Hmmm. - zr | |
3527 * | |
3528 * Addendum: we can't really ensure that this is never called in
edit | |
3529 * mode, so now we have a parameter to verify it. - brecht | |
3530 */ | |
3531 if (!(flags & SUBSURF_IN_EDIT_MODE) && smd->emCache) { | |
3532 ccgSubSurf_free(smd->emCache); | |
3533 smd->emCache = NULL; | |
3534 } | |
3535 | |
3536 if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) { | |
3537 smd->mCache = ss = _getSubSurf(smd->mCache, levels, 3, u
seAging | CCG_CALC_NORMALS); | |
3538 | |
3539 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); | |
3540 | |
3541 result = getCCGDerivedMesh(smd->mCache, | |
3542 drawInteriorEdges, | |
3543 useSubsurfUv, dm); | |
3544 } | |
3545 else { | |
3546 CCGFlags ccg_flags = CCG_USE_ARENA | CCG_CALC_NORMALS; | |
3547 ························ | |
3548 if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) { | |
3549 ccgSubSurf_free(smd->mCache); | |
3550 smd->mCache = NULL; | |
3551 } | |
3552 | |
3553 if (flags & SUBSURF_ALLOC_PAINT_MASK) | |
3554 ccg_flags |= CCG_ALLOC_MASK; | |
3555 | |
3556 ss = _getSubSurf(NULL, levels, 3, ccg_flags); | |
3557 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); | |
3558 | |
3559 result = getCCGDerivedMesh(ss, drawInteriorEdges, useSub
surfUv, dm); | |
3560 | |
3561 if (flags & SUBSURF_IS_FINAL_CALC) | |
3562 smd->mCache = ss; | |
3563 else | |
3564 result->freeSS = 1; | |
3565 | |
3566 if (flags & SUBSURF_ALLOC_PAINT_MASK) | |
3567 ccgSubSurf_setNumLayers(ss, 4); | |
3568 } | |
3569 } | |
3570 | |
3571 return (DerivedMesh *)result; | |
3572 } | |
3573 | |
3574 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])· | |
3575 { | |
3576 /* Finds the subsurf limit positions for the verts in a mesh· | |
3577 * and puts them in an array of floats. Please note that the· | |
3578 * calculated vert positions is incorrect for the verts· | |
3579 * on the boundary of the mesh. | |
3580 */ | |
3581 CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA); | |
3582 float edge_sum[3], face_sum[3]; | |
3583 CCGVertIterator *vi; | |
3584 DerivedMesh *dm = CDDM_from_mesh(me, NULL); | |
3585 | |
3586 ss_sync_from_derivedmesh(ss, dm, NULL, 0); | |
3587 | |
3588 vi = ccgSubSurf_getVertIterator(ss); | |
3589 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { | |
3590 CCGVert *v = ccgVertIterator_getCurrent(vi); | |
3591 int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); | |
3592 int N = ccgSubSurf_getVertNumEdges(v); | |
3593 int numFaces = ccgSubSurf_getVertNumFaces(v); | |
3594 float *co; | |
3595 int i; | |
3596 | |
3597 edge_sum[0] = edge_sum[1] = edge_sum[2] = 0.0; | |
3598 face_sum[0] = face_sum[1] = face_sum[2] = 0.0; | |
3599 | |
3600 for (i = 0; i < N; i++) { | |
3601 CCGEdge *e = ccgSubSurf_getVertEdge(v, i); | |
3602 add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(s
s, e, 1)); | |
3603 } | |
3604 for (i = 0; i < numFaces; i++) { | |
3605 CCGFace *f = ccgSubSurf_getVertFace(v, i); | |
3606 add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f)); | |
3607 } | |
3608 | |
3609 /* ad-hoc correction for boundary vertices, to at least avoid th
em | |
3610 * moving completely out of place (brecht) */ | |
3611 if (numFaces && numFaces != N) | |
3612 mul_v3_fl(face_sum, (float)N / (float)numFaces); | |
3613 | |
3614 co = ccgSubSurf_getVertData(ss, v); | |
3615 positions_r[idx][0] = (co[0] * N * N + edge_sum[0] * 4 + face_su
m[0]) / (N * (N + 5)); | |
3616 positions_r[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_su
m[1]) / (N * (N + 5)); | |
3617 positions_r[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_su
m[2]) / (N * (N + 5)); | |
3618 } | |
3619 ccgVertIterator_free(vi); | |
3620 | |
3621 ccgSubSurf_free(ss); | |
3622 | |
3623 dm->release(dm); | |
3624 } | |
LEFT | RIGHT |