4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2005 Blender Foundation.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
30 /** \file blender/blenkernel/intern/subsurf_ccg.c
41 #include "MEM_guardedalloc.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_modifier_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_scene_types.h"
49 #include "BLI_blenlib.h"
50 #include "BLI_edgehash.h"
52 #include "BLI_memarena.h"
54 #include "BLI_utildefines.h"
56 #include "BKE_cdderivedmesh.h"
57 #include "BKE_global.h"
59 #include "BKE_modifier.h"
60 #include "BKE_paint.h"
61 #include "BKE_scene.h"
62 #include "BKE_subsurf.h"
66 #include "BIF_glutil.h"
69 #include "GPU_extensions.h"
70 #include "GPU_material.h"
72 #include "CCGSubSurf.h"
74 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v);
75 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e);
76 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f);
77 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
81 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
82 return BLI_memarena_alloc(a, numBytes);
84 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
85 void *p2 = BLI_memarena_alloc(a, newSize);
87 memcpy(p2, ptr, oldSize);
91 static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr)) {
93 static void arena_release(CCGAllocatorHDL a) {
97 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int UNUSED(useFlatSubdiv)) {
101 /* subdivLevels==0 is not allowed */
102 subdivLevels = MAX2(subdivLevels, 1);
107 useAging = !!useAging;
108 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
110 if (oldUseAging!=useAging) {
111 ccgSubSurf_free(prevSS);
113 ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
120 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
122 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
124 ifc.vertDataSize = sizeof(DMGridData);
127 CCGAllocatorIFC allocatorIFC;
128 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16), "subsurf arena");
130 allocatorIFC.alloc = arena_alloc;
131 allocatorIFC.realloc = arena_realloc;
132 allocatorIFC.free = arena_free;
133 allocatorIFC.release = arena_release;
135 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
137 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
141 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
144 ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(DMGridData, no));
149 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
150 CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
151 CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
152 int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
153 int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
154 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
158 } else if (x==edgeSize-1) {
161 return edgeBase + x-1;
164 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
165 int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
166 int numVerts = ccgSubSurf_getFaceNumVerts(f);
168 if (x==gridSize-1 && y==gridSize-1) {
169 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
170 return *((int*) ccgSubSurf_getVertUserData(ss, v));
171 } else if (x==gridSize-1) {
172 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
173 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
174 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
175 if (v==ccgSubSurf_getEdgeVert0(e)) {
176 return edgeBase + (gridSize-1-y)-1;
178 return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
180 } else if (y==gridSize-1) {
181 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
182 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
183 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
184 if (v==ccgSubSurf_getEdgeVert0(e)) {
185 return edgeBase + (gridSize-1-x)-1;
187 return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
189 } else if (x==0 && y==0) {
192 S = (S+numVerts-1)%numVerts;
193 return faceBase + 1 + (gridSize-2)*S + (y-1);
195 return faceBase + 1 + (gridSize-2)*S + (x-1);
197 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
201 static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) {
202 unsigned int *fv = &mf->v1;
204 int j, nverts= mf->v4? 4: 3;
206 for (j=0; j<nverts; j++, fv++) {
207 for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) {
214 fverts[j]= SET_INT_IN_POINTER(nv->f*4 + nv->tfindex);
218 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MTFace *tface) {
219 MFace *mface = dm->getFaceArray(dm);
220 MVert *mvert = dm->getVertArray(dm);
221 int totvert = dm->getNumVerts(dm);
222 int totface = dm->getNumFaces(dm);
227 CCGVertHDL fverts[4];
229 float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
231 limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
232 vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit);
236 ccgSubSurf_initFullSync(ss);
238 /* create vertices */
239 for (i=0; i<totvert; i++) {
240 if (!get_uv_map_vert(vmap, i))
243 for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next)
247 seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED);
249 for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
252 CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
255 uv[0]= (tface+v->f)->uv[v->tfindex][0];
256 uv[1]= (tface+v->f)->uv[v->tfindex][1];
259 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
265 ehash = BLI_edgehash_new();
267 for (i=0; i<totface; i++) {
268 MFace *mf = &((MFace*) mface)[i];
269 int nverts= mf->v4? 4: 3;
270 CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i));
271 unsigned int *fv = &mf->v1;
273 get_face_uv_map_vert(vmap, mf, i, fverts);
275 for (j=0; j<nverts; j++) {
276 int v0 = GET_INT_FROM_POINTER(fverts[j]);
277 int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]);
278 MVert *mv0 = mvert + *(fv+j);
279 MVert *mv1 = mvert + *(fv+((j+1)%nverts));
281 if (!BLI_edgehash_haskey(ehash, v0, v1)) {
282 CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j);
283 CCGEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j);
286 if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
287 crease = creaseFactor;
289 crease = ccgSubSurf_getEdgeCrease(orige);
291 ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e);
292 BLI_edgehash_insert(ehash, v0, v1, NULL);
297 BLI_edgehash_free(ehash, NULL);
300 for (i=0; i<totface; i++) {
301 MFace *mf = &((MFace*) mface)[i];
302 int nverts= mf->v4? 4: 3;
305 get_face_uv_map_vert(vmap, mf, i, fverts);
306 ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f);
309 free_uv_vert_map(vmap);
310 ccgSubSurf_processSync(ss);
315 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
321 int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
322 MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n);
323 MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
325 if(!dmtface || !tface)
328 /* create a CCGSubSurf from uv's */
329 uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0);
331 if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) {
332 ccgSubSurf_free(uvss);
336 /* get some info from CCGSubSurf */
337 totface = ccgSubSurf_getNumFaces(uvss);
338 /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
339 gridSize = ccgSubSurf_getGridSize(uvss);
340 gridFaces = gridSize - 1;
342 /* make a map from original faces to CCGFaces */
343 faceMap = MEM_mallocN(totface*sizeof(*faceMap), "facemapuv");
345 fi = ccgSubSurf_getFaceIterator(uvss);
346 for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
347 CCGFace *f = ccgFaceIterator_getCurrent(fi);
348 faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(uvss, f))] = f;
350 ccgFaceIterator_free(fi);
352 /* load coordinates from uvss into tface */
355 for(index = 0; index < totface; index++) {
356 CCGFace *f = faceMap[index];
357 int numVerts = ccgSubSurf_getFaceNumVerts(f);
359 for (S=0; S<numVerts; S++) {
360 DMGridData *faceGridData= ccgSubSurf_getFaceGridDataArray(uvss, f, S);
362 for(y = 0; y < gridFaces; y++) {
363 for(x = 0; x < gridFaces; x++) {
364 float *a = faceGridData[(y + 0)*gridSize + x + 0].co;
365 float *b = faceGridData[(y + 0)*gridSize + x + 1].co;
366 float *c = faceGridData[(y + 1)*gridSize + x + 1].co;
367 float *d = faceGridData[(y + 1)*gridSize + x + 0].co;
369 tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1];
370 tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1];
371 tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1];
372 tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1];
380 ccgSubSurf_free(uvss);
385 static void calc_ss_weights(int gridFaces,
386 FaceVertWeight **qweight, FaceVertWeight **tweight)
388 FaceVertWeight *qw, *tw;
390 int numWeights = gridFaces * gridFaces;
392 *tweight = MEM_mallocN(sizeof(**tweight) * numWeights, "ssTriWeight");
393 *qweight = MEM_mallocN(sizeof(**qweight) * numWeights, "ssQuadWeight");
398 for (y = 0; y < gridFaces; y++) {
399 for (x = 0; x < gridFaces; x++) {
400 for (j = 0; j < 4; j++) {
401 int fx = x + (j == 2 || j == 3);
402 int fy = y + (j == 1 || j == 2);
403 float x_v = (float) fx / gridFaces;
404 float y_v = (float) fy / gridFaces;
405 float tx_v = (1.0f - x_v), ty_v = (1.0f - y_v);
406 float center = (1.0f / 3.0f) * tx_v * ty_v;
408 (*tw)[j][0] = center + 0.5f * tx_v * y_v;
409 (*tw)[j][2] = center + 0.5f * x_v * ty_v;
410 (*tw)[j][1] = 1.0f - (*tw)[j][0] - (*tw)[j][2];
416 (*qw)[j][3] = tx_v * ty_v;
417 (*qw)[j][0] = (*qw)[j][3] + tx_v * y_v;
418 (*qw)[j][2] = (*qw)[j][3] + x_v * ty_v;
419 (*qw)[j][1] = 1.0f - (*qw)[j][0] - (*qw)[j][2] - (*qw)[j][3];
428 static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
429 float (*vertexCos)[3], int useFlatSubdiv)
431 float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
432 CCGVertHDL fVerts[4];
433 int totvert = dm->getNumVerts(dm);
434 int totedge = dm->getNumEdges(dm);
435 int totface = dm->getNumFaces(dm);
438 MVert *mvert = dm->getVertArray(dm);
439 MEdge *medge = dm->getEdgeArray(dm);
440 MFace *mface = dm->getFaceArray(dm);
445 ccgSubSurf_initFullSync(ss);
448 index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
449 for(i = 0; i < totvert; i++, mv++) {
453 ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v);
455 ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v);
458 ((int*)ccgSubSurf_getVertUserData(ss, v))[1] = (index)? *index++: i;
462 index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
463 for(i = 0; i < totedge; i++, me++) {
467 crease = useFlatSubdiv ? creaseFactor :
468 me->crease * creaseFactor / 255.0f;
470 ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1),
471 SET_INT_IN_POINTER(me->v2), crease, &e);
473 ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index)? *index++: i;
477 index = (int *)dm->getFaceDataArray(dm, CD_ORIGINDEX);
478 for (i = 0; i < totface; i++, mf++) {
481 fVerts[0] = SET_INT_IN_POINTER(mf->v1);
482 fVerts[1] = SET_INT_IN_POINTER(mf->v2);
483 fVerts[2] = SET_INT_IN_POINTER(mf->v3);
484 fVerts[3] = SET_INT_IN_POINTER(mf->v4);
486 // this is very bad, means mesh is internally consistent.
487 // it is not really possible to continue without modifying
488 // other parts of code significantly to handle missing faces.
489 // since this really shouldn't even be possible we just bail.
490 if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), fVerts[3] ? 4 : 3,
491 fVerts, &f) == eCCGError_InvalidValue) {
492 static int hasGivenError = 0;
495 //XXX error("Unrecoverable error in SubSurf calculation,"
496 // " mesh is inconsistent.");
504 ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = (index)? *index++: i;
507 ccgSubSurf_processSync(ss);
512 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v) {
513 return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
516 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e) {
517 return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
520 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) {
521 return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
524 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
525 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
526 CCGSubSurf *ss = ccgdm->ss;
527 CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
528 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
529 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
530 int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
531 int gridSize = ccgSubSurf_getGridSize(ss);
533 if (!ccgSubSurf_getNumVerts(ss))
534 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
536 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
537 CCGVert *v = ccgVertIterator_getCurrent(vi);
538 float *co = ccgSubSurf_getVertData(ss, v);
540 DO_MINMAX(co, min_r, max_r);
543 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
544 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
545 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
547 for (i=0; i<edgeSize; i++)
548 DO_MINMAX(edgeData[i].co, min_r, max_r);
551 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
552 CCGFace *f = ccgFaceIterator_getCurrent(fi);
553 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
555 for (S=0; S<numVerts; S++) {
556 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
558 for (y=0; y<gridSize; y++)
559 for (x=0; x<gridSize; x++)
560 DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
564 ccgFaceIterator_free(fi);
565 ccgEdgeIterator_free(ei);
566 ccgVertIterator_free(vi);
568 static int ccgDM_getNumVerts(DerivedMesh *dm) {
569 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
571 return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
573 static int ccgDM_getNumEdges(DerivedMesh *dm) {
574 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
576 return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
578 static int ccgDM_getNumFaces(DerivedMesh *dm) {
579 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
581 return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
584 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
586 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
587 CCGSubSurf *ss = ccgdm->ss;
591 memset(mv, 0, sizeof(*mv));
593 if((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
594 /* this vert comes from face data */
595 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
597 int x, y, grid, numVerts;
599 int gridSize = ccgSubSurf_getGridSize(ss);
601 int gridInternalVerts;
606 while(i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert)
609 f = ccgdm->faceMap[i].face;
610 numVerts = ccgSubSurf_getFaceNumVerts(f);
612 gridSideVerts = gridSize - 2;
613 gridInternalVerts = gridSideVerts * gridSideVerts;
615 gridSideEnd = 1 + numVerts * gridSideVerts;
616 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
618 offset = vertNum - ccgdm->faceMap[i].startVert;
620 vd = ccgSubSurf_getFaceCenterData(f);
621 copy_v3_v3(mv->co, vd->co);
622 normal_float_to_short_v3(mv->no, vd->no);
623 } else if(offset < gridSideEnd) {
625 grid = offset / gridSideVerts;
626 x = offset % gridSideVerts + 1;
627 vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
628 copy_v3_v3(mv->co, vd->co);
629 normal_float_to_short_v3(mv->no, vd->no);
630 } else if(offset < gridInternalEnd) {
631 offset -= gridSideEnd;
632 grid = offset / gridInternalVerts;
633 offset %= gridInternalVerts;
634 y = offset / gridSideVerts + 1;
635 x = offset % gridSideVerts + 1;
636 vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
637 copy_v3_v3(mv->co, vd->co);
638 normal_float_to_short_v3(mv->no, vd->no);
640 } else if((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
641 /* this vert comes from edge data */
643 int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
647 while(i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert)
650 e = ccgdm->edgeMap[i].edge;
652 x = vertNum - ccgdm->edgeMap[i].startVert + 1;
653 vd = ccgSubSurf_getEdgeData(ss, e, x);
654 copy_v3_v3(mv->co, vd->co);
655 normal_float_to_short_v3(mv->no, vd->no);
657 /* this vert comes from vert data */
659 i = vertNum - ccgdm->vertMap[0].startVert;
661 v = ccgdm->vertMap[i].vert;
662 vd = ccgSubSurf_getVertData(ss, v);
663 copy_v3_v3(mv->co, vd->co);
664 normal_float_to_short_v3(mv->no, vd->no);
668 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float co_r[3])
672 ccgDM_getFinalVert(dm, vertNum, &mvert);
673 VECCOPY(co_r, mvert.co);
676 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3])
680 ccgDM_getFinalVert(dm, vertNum, &mvert);
681 normal_short_to_float_v3(no_r, mvert.no);
684 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
686 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
687 CCGSubSurf *ss = ccgdm->ss;
690 memset(med, 0, sizeof(*med));
692 if(edgeNum < ccgdm->edgeMap[0].startEdge) {
693 /* this edge comes from face data */
694 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
696 int x, y, grid /*, numVerts*/;
698 int gridSize = ccgSubSurf_getGridSize(ss);
699 int edgeSize = ccgSubSurf_getEdgeSize(ss);
701 int gridInternalEdges;
704 while(i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge)
707 f = ccgdm->faceMap[i].face;
708 /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
710 gridSideEdges = gridSize - 1;
711 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
713 offset = edgeNum - ccgdm->faceMap[i].startEdge;
714 grid = offset / (gridSideEdges + gridInternalEdges);
715 offset %= (gridSideEdges + gridInternalEdges);
717 if(offset < gridSideEdges) {
719 med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
720 med->v2 = getFaceIndex(ss, f, grid, x+1, 0, edgeSize, gridSize);
722 offset -= gridSideEdges;
723 x = (offset / 2) / gridSideEdges + 1;
724 y = (offset / 2) % gridSideEdges;
725 if(offset % 2 == 0) {
726 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
727 med->v2 = getFaceIndex(ss, f, grid, x, y+1, edgeSize, gridSize);
729 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
730 med->v2 = getFaceIndex(ss, f, grid, y+1, x, edgeSize, gridSize);
734 /* this vert comes from edge data */
736 int edgeSize = ccgSubSurf_getEdgeSize(ss);
739 unsigned int flags = 0;
741 i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
743 e = ccgdm->edgeMap[i].edge;
745 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
747 x = edgeNum - ccgdm->edgeMap[i].startEdge;
749 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
750 med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
752 edgeFlag = (ccgdm->edgeFlags)? &ccgdm->edgeFlags[i]: NULL;
754 flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
755 | ME_EDGEDRAW | ME_EDGERENDER;
757 flags |= ME_EDGEDRAW | ME_EDGERENDER;
763 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
765 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
766 CCGSubSurf *ss = ccgdm->ss;
767 int gridSize = ccgSubSurf_getGridSize(ss);
768 int edgeSize = ccgSubSurf_getEdgeSize(ss);
769 int gridSideEdges = gridSize - 1;
770 int gridFaces = gridSideEdges * gridSideEdges;
777 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
778 char *faceFlags = ccgdm->faceFlags;
780 memset(mf, 0, sizeof(*mf));
783 while(i < lastface && faceNum >= ccgdm->faceMap[i + 1].startFace)
786 f = ccgdm->faceMap[i].face;
787 /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
789 offset = faceNum - ccgdm->faceMap[i].startFace;
790 grid = offset / gridFaces;
792 y = offset / gridSideEdges;
793 x = offset % gridSideEdges;
795 mf->v1 = getFaceIndex(ss, f, grid, x+0, y+0, edgeSize, gridSize);
796 mf->v2 = getFaceIndex(ss, f, grid, x+0, y+1, edgeSize, gridSize);
797 mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize);
798 mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize);
801 mf->flag = faceFlags[i*2];
802 mf->mat_nr = faceFlags[i*2+1];
804 else mf->flag = ME_SMOOTH;
807 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
809 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
810 CCGSubSurf *ss = ccgdm->ss;
813 int totvert, totedge, totface;
814 int gridSize = ccgSubSurf_getGridSize(ss);
815 int edgeSize = ccgSubSurf_getEdgeSize(ss);
818 totface = ccgSubSurf_getNumFaces(ss);
819 for(index = 0; index < totface; index++) {
820 CCGFace *f = ccgdm->faceMap[index].face;
821 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
823 vd= ccgSubSurf_getFaceCenterData(f);
824 copy_v3_v3(mvert[i].co, vd->co);
825 normal_float_to_short_v3(mvert[i].no, vd->no);
828 for(S = 0; S < numVerts; S++) {
829 for(x = 1; x < gridSize - 1; x++, i++) {
830 vd= ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
831 copy_v3_v3(mvert[i].co, vd->co);
832 normal_float_to_short_v3(mvert[i].no, vd->no);
836 for(S = 0; S < numVerts; S++) {
837 for(y = 1; y < gridSize - 1; y++) {
838 for(x = 1; x < gridSize - 1; x++, i++) {
839 vd= ccgSubSurf_getFaceGridData(ss, f, S, x, y);
840 copy_v3_v3(mvert[i].co, vd->co);
841 normal_float_to_short_v3(mvert[i].no, vd->no);
847 totedge = ccgSubSurf_getNumEdges(ss);
848 for(index = 0; index < totedge; index++) {
849 CCGEdge *e = ccgdm->edgeMap[index].edge;
852 for(x = 1; x < edgeSize - 1; x++, i++) {
853 vd= ccgSubSurf_getEdgeData(ss, e, x);
854 copy_v3_v3(mvert[i].co, vd->co);
855 /* This gives errors with -debug-fpe
856 * the normals dont seem to be unit length.
857 * this is most likely caused by edges with no
858 * faces which are now zerod out, see comment in:
859 * ccgSubSurf__calcVertNormals(), - campbell */
860 normal_float_to_short_v3(mvert[i].no, vd->no);
864 totvert = ccgSubSurf_getNumVerts(ss);
865 for(index = 0; index < totvert; index++) {
866 CCGVert *v = ccgdm->vertMap[index].vert;
868 vd= ccgSubSurf_getVertData(ss, v);
869 copy_v3_v3(mvert[i].co, vd->co);
870 normal_float_to_short_v3(mvert[i].no, vd->no);
875 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
877 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
878 CCGSubSurf *ss = ccgdm->ss;
880 int totedge, totface;
881 int gridSize = ccgSubSurf_getGridSize(ss);
882 int edgeSize = ccgSubSurf_getEdgeSize(ss);
884 short *edgeFlags = ccgdm->edgeFlags;
886 totface = ccgSubSurf_getNumFaces(ss);
887 for(index = 0; index < totface; index++) {
888 CCGFace *f = ccgdm->faceMap[index].face;
889 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
891 for(S = 0; S < numVerts; S++) {
892 for(x = 0; x < gridSize - 1; x++) {
893 MEdge *med = &medge[i];
895 if(ccgdm->drawInteriorEdges)
896 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
897 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
898 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
902 for(x = 1; x < gridSize - 1; x++) {
903 for(y = 0; y < gridSize - 1; y++) {
907 if(ccgdm->drawInteriorEdges)
908 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
909 med->v1 = getFaceIndex(ss, f, S, x, y,
911 med->v2 = getFaceIndex(ss, f, S, x, y + 1,
916 if(ccgdm->drawInteriorEdges)
917 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
918 med->v1 = getFaceIndex(ss, f, S, y, x,
920 med->v2 = getFaceIndex(ss, f, S, y + 1, x,
928 totedge = ccgSubSurf_getNumEdges(ss);
929 for(index = 0; index < totedge; index++) {
930 CCGEdge *e = ccgdm->edgeMap[index].edge;
931 unsigned int flags = 0;
933 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
935 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
939 flags |= (edgeFlags[index] & (ME_SEAM | ME_SHARP))
940 | ME_EDGEDRAW | ME_EDGERENDER;
943 flags |= ME_EDGEDRAW | ME_EDGERENDER;
946 for(x = 0; x < edgeSize - 1; x++) {
947 MEdge *med = &medge[i];
948 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
949 med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
956 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
958 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
959 CCGSubSurf *ss = ccgdm->ss;
962 int gridSize = ccgSubSurf_getGridSize(ss);
963 int edgeSize = ccgSubSurf_getEdgeSize(ss);
965 char *faceFlags = ccgdm->faceFlags;
967 totface = ccgSubSurf_getNumFaces(ss);
968 for(index = 0; index < totface; index++) {
969 CCGFace *f = ccgdm->faceMap[index].face;
970 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
971 int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
972 int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
974 for(S = 0; S < numVerts; S++) {
975 for(y = 0; y < gridSize - 1; y++) {
976 for(x = 0; x < gridSize - 1; x++) {
977 MFace *mf = &mface[i];
978 mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
980 mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
982 mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
984 mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
996 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
997 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
998 CCGSubSurf *ss = ccgdm->ss;
999 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1000 int gridSize = ccgSubSurf_getGridSize(ss);
1002 CCGVertIterator *vi;
1003 CCGEdgeIterator *ei;
1004 CCGFaceIterator *fi;
1008 int index, totvert, totedge, totface;
1010 totvert = ccgSubSurf_getNumVerts(ss);
1011 vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1012 vi = ccgSubSurf_getVertIterator(ss);
1013 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1014 CCGVert *v = ccgVertIterator_getCurrent(vi);
1016 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1018 ccgVertIterator_free(vi);
1020 totedge = ccgSubSurf_getNumEdges(ss);
1021 edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1022 ei = ccgSubSurf_getEdgeIterator(ss);
1023 for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1024 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1026 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1029 totface = ccgSubSurf_getNumFaces(ss);
1030 faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1031 fi = ccgSubSurf_getFaceIterator(ss);
1032 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1033 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1035 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
1037 ccgFaceIterator_free(fi);
1040 for (index=0; index<totface; index++) {
1041 CCGFace *f = faceMap2[index];
1042 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1044 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
1046 for (S=0; S<numVerts; S++) {
1047 for (x=1; x<gridSize-1; x++) {
1048 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1052 for (S=0; S<numVerts; S++) {
1053 for (y=1; y<gridSize-1; y++) {
1054 for (x=1; x<gridSize-1; x++) {
1055 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1061 for (index=0; index<totedge; index++) {
1062 CCGEdge *e= edgeMap2[index];
1065 for (x=1; x<edgeSize-1; x++) {
1066 copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1070 for (index=0; index<totvert; index++) {
1071 CCGVert *v = vertMap2[index];
1072 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
1075 MEM_freeN(vertMap2);
1076 MEM_freeN(edgeMap2);
1077 MEM_freeN(faceMap2);
1079 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1080 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1081 CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
1083 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1084 CCGVert *v = ccgVertIterator_getCurrent(vi);
1085 DMGridData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1086 int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
1089 func(userData, index, vd->co, vd->no, NULL);
1092 ccgVertIterator_free(vi);
1094 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1095 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1096 CCGSubSurf *ss = ccgdm->ss;
1097 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1098 int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1100 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1101 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1102 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1103 int index = ccgDM_getEdgeMapIndex(ss, e);
1106 for (i=0; i<edgeSize-1; i++)
1107 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1111 ccgEdgeIterator_free(ei);
1114 static void ccgDM_drawVerts(DerivedMesh *dm) {
1115 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1116 CCGSubSurf *ss = ccgdm->ss;
1117 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1118 int gridSize = ccgSubSurf_getGridSize(ss);
1119 CCGVertIterator *vi;
1120 CCGEdgeIterator *ei;
1121 CCGFaceIterator *fi;
1124 vi = ccgSubSurf_getVertIterator(ss);
1125 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1126 CCGVert *v = ccgVertIterator_getCurrent(vi);
1127 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1129 ccgVertIterator_free(vi);
1131 ei = ccgSubSurf_getEdgeIterator(ss);
1132 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1133 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1136 for (x=1; x<edgeSize-1; x++)
1137 glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1139 ccgEdgeIterator_free(ei);
1141 fi = ccgSubSurf_getFaceIterator(ss);
1142 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1143 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1144 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1146 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1147 for (S=0; S<numVerts; S++)
1148 for (x=1; x<gridSize-1; x++)
1149 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1150 for (S=0; S<numVerts; S++)
1151 for (y=1; y<gridSize-1; y++)
1152 for (x=1; x<gridSize-1; x++)
1153 glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1155 ccgFaceIterator_free(fi);
1159 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
1161 if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
1165 BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void***)&faces, &totface);
1167 ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
1168 ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
1174 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(drawAllEdges)) {
1175 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1176 CCGSubSurf *ss = ccgdm->ss;
1177 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1178 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1179 int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1180 int totedge = ccgSubSurf_getNumEdges(ss);
1181 int gridSize = ccgSubSurf_getGridSize(ss);
1184 ccgdm_pbvh_update(ccgdm);
1186 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1188 for (j=0; j< totedge; j++) {
1189 CCGEdge *e = ccgdm->edgeMap[j].edge;
1190 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1192 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1195 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1198 if (useAging && !(G.f&G_BACKBUFSEL)) {
1199 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1200 glColor3ub(0, ageCol>0?ageCol:0, 0);
1203 glBegin(GL_LINE_STRIP);
1204 for (i=0; i<edgeSize-1; i++) {
1205 glVertex3fv(edgeData[i].co);
1206 glVertex3fv(edgeData[i+1].co);
1211 if (useAging && !(G.f&G_BACKBUFSEL)) {
1212 glColor3ub(0, 0, 0);
1215 if (ccgdm->drawInteriorEdges) {
1216 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1217 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1218 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1220 for (S=0; S<numVerts; S++) {
1221 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1223 glBegin(GL_LINE_STRIP);
1224 for (x=0; x<gridSize; x++)
1225 glVertex3fv(faceGridData[x].co);
1227 for (y=1; y<gridSize-1; y++) {
1228 glBegin(GL_LINE_STRIP);
1229 for (x=0; x<gridSize; x++)
1230 glVertex3fv(faceGridData[y*gridSize + x].co);
1233 for (x=1; x<gridSize-1; x++) {
1234 glBegin(GL_LINE_STRIP);
1235 for (y=0; y<gridSize; y++)
1236 glVertex3fv(faceGridData[y*gridSize + x].co);
1243 ccgFaceIterator_free(fi);
1244 ccgEdgeIterator_free(ei);
1246 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1247 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1248 CCGSubSurf *ss = ccgdm->ss;
1249 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1250 int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1252 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1253 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1254 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1256 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1257 glBegin(GL_LINE_STRIP);
1258 for (i=0; i<edgeSize-1; i++) {
1259 glVertex3fv(edgeData[i].co);
1260 glVertex3fv(edgeData[i+1].co);
1266 ccgEdgeIterator_free(ei);
1269 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1271 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1272 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1275 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1276 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1277 no[2] = b_dX*a_cY - b_dY*a_cX;
1279 /* don't normalize, GL_NORMALIZE is enabled */
1283 /* Only used by non-editmesh types */
1284 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
1285 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1286 CCGSubSurf *ss = ccgdm->ss;
1287 CCGFaceIterator *fi;
1288 int gridSize = ccgSubSurf_getGridSize(ss);
1289 char *faceFlags = ccgdm->faceFlags;
1290 int step = (fast)? gridSize-1: 1;
1292 ccgdm_pbvh_update(ccgdm);
1294 if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1295 if(dm->numFaceData) {
1296 /* should be per face */
1297 if(!setMaterial(faceFlags[1]+1, NULL))
1300 glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
1301 BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH));
1302 glShadeModel(GL_FLAT);
1308 fi = ccgSubSurf_getFaceIterator(ss);
1309 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1310 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1311 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1312 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1313 int drawSmooth, mat_nr;
1316 drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1317 mat_nr= faceFlags[index*2 + 1];
1324 if (!setMaterial(mat_nr+1, NULL))
1327 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1328 for (S=0; S<numVerts; S++) {
1329 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1332 for (y=0; y<gridSize-1; y+=step) {
1333 glBegin(GL_QUAD_STRIP);
1334 for (x=0; x<gridSize; x+=step) {
1335 DMGridData *a = &faceGridData[(y+0)*gridSize + x];
1336 DMGridData *b = &faceGridData[(y+step)*gridSize + x];
1347 for (y=0; y<gridSize-1; y+=step) {
1348 for (x=0; x<gridSize-1; x+=step) {
1349 float *a = faceGridData[(y+0)*gridSize + x].co;
1350 float *b = faceGridData[(y+0)*gridSize + x + step].co;
1351 float *c = faceGridData[(y+step)*gridSize + x + step].co;
1352 float *d = faceGridData[(y+step)*gridSize + x].co;
1354 ccgDM_glNormalFast(a, b, c, d);
1367 ccgFaceIterator_free(fi);
1370 /* Only used by non-editmesh types */
1371 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
1372 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1373 CCGSubSurf *ss = ccgdm->ss;
1374 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1375 GPUVertexAttribs gattribs;
1376 DMVertexAttribs attribs= {{{NULL}}};
1377 MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
1378 int gridSize = ccgSubSurf_getGridSize(ss);
1379 int gridFaces = gridSize - 1;
1380 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1381 int transp, orig_transp, new_transp;
1382 char *faceFlags = ccgdm->faceFlags;
1383 int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
1385 ccgdm_pbvh_update(ccgdm);
1389 transp = GPU_get_material_blend_mode();
1390 orig_transp = transp;
1392 #define PASSATTRIB(dx, dy, vert) { \
1393 if(attribs.totorco) { \
1394 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize); \
1395 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \
1397 for(b = 0; b < attribs.tottface; b++) { \
1398 MTFace *tf = &attribs.tface[b].array[a]; \
1399 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \
1401 for(b = 0; b < attribs.totmcol; b++) { \
1402 MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \
1404 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
1405 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
1407 if(attribs.tottang) { \
1408 float *tang = attribs.tang.array[a*4 + vert]; \
1409 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \
1413 totface = ccgSubSurf_getNumFaces(ss);
1414 for(a = 0, i = 0; i < totface; i++) {
1415 CCGFace *f = ccgdm->faceMap[i].face;
1416 int S, x, y, drawSmooth;
1417 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1418 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1420 numVerts = ccgSubSurf_getFaceNumVerts(f);
1423 drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1424 new_matnr= faceFlags[index*2 + 1] + 1;
1431 if(new_matnr != matnr) {
1432 doDraw = setMaterial(matnr = new_matnr, &gattribs);
1434 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1437 if(!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && !setDrawOptions(userData, origIndex))) {
1438 a += gridFaces*gridFaces*numVerts;
1443 new_transp = tf[i].transp;
1445 if(new_transp != transp) {
1446 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1447 GPU_set_material_blend_mode(orig_transp);
1449 GPU_set_material_blend_mode(new_transp);
1450 transp = new_transp;
1454 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1455 for (S=0; S<numVerts; S++) {
1456 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1457 DMGridData *vda, *vdb;
1460 for (y=0; y<gridFaces; y++) {
1461 glBegin(GL_QUAD_STRIP);
1462 for (x=0; x<gridFaces; x++) {
1463 vda = &faceGridData[(y+0)*gridSize + x];
1464 vdb = &faceGridData[(y+1)*gridSize + x];
1466 PASSATTRIB(0, 0, 0);
1467 glNormal3fv(vda->no);
1468 glVertex3fv(vda->co);
1470 PASSATTRIB(0, 1, 1);
1471 glNormal3fv(vdb->no);
1472 glVertex3fv(vdb->co);
1474 if(x != gridFaces-1)
1478 vda = &faceGridData[(y+0)*gridSize + x];
1479 vdb = &faceGridData[(y+1)*gridSize + x];
1481 PASSATTRIB(0, 0, 3);
1482 glNormal3fv(vda->no);
1483 glVertex3fv(vda->co);
1485 PASSATTRIB(0, 1, 2);
1486 glNormal3fv(vdb->no);
1487 glVertex3fv(vdb->co);
1495 for (y=0; y<gridFaces; y++) {
1496 for (x=0; x<gridFaces; x++) {
1497 float *aco = faceGridData[(y+0)*gridSize + x].co;
1498 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1499 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1500 float *dco = faceGridData[(y+1)*gridSize + x].co;
1502 ccgDM_glNormalFast(aco, bco, cco, dco);
1504 PASSATTRIB(0, 1, 1);
1506 PASSATTRIB(1, 1, 2);
1508 PASSATTRIB(1, 0, 3);
1510 PASSATTRIB(0, 0, 0);
1523 ccgFaceIterator_free(fi);
1526 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1527 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1530 static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
1531 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1532 CCGSubSurf *ss = ccgdm->ss;
1533 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1534 int gridSize = ccgSubSurf_getGridSize(ss);
1535 unsigned char *cp1, *cp2;
1538 ccgdm_pbvh_update(ccgdm);
1548 glShadeModel(GL_SMOOTH);
1551 glEnable(GL_CULL_FACE);
1555 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1556 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1557 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1559 for (S=0; S<numVerts; S++) {
1560 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1561 for (y=0; y<gridSize-1; y++) {
1562 for (x=0; x<gridSize-1; x++) {
1563 float *a = faceGridData[(y+0)*gridSize + x].co;
1564 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1565 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1566 float *d = faceGridData[(y+1)*gridSize + x].co;
1568 glColor3ub(cp1[3], cp1[2], cp1[1]);
1570 glColor3ub(cp1[7], cp1[6], cp1[5]);
1572 glColor3ub(cp1[11], cp1[10], cp1[9]);
1574 glColor3ub(cp1[15], cp1[14], cp1[13]);
1578 glColor3ub(cp2[15], cp2[14], cp2[13]);
1580 glColor3ub(cp2[11], cp2[10], cp2[9]);
1582 glColor3ub(cp2[7], cp2[6], cp2[5]);
1584 glColor3ub(cp2[3], cp2[2], cp2[1]);
1596 ccgFaceIterator_free(fi);
1599 static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
1600 int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
1601 int (*drawParamsMapped)(void *userData, int index),
1604 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1605 CCGSubSurf *ss = ccgdm->ss;
1606 MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
1607 MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1608 char *faceFlags = ccgdm->faceFlags;
1609 int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1610 int gridFaces = gridSize - 1;
1612 ccgdm_pbvh_update(ccgdm);
1615 mcol = dm->getFaceDataArray(dm, CD_MCOL);
1617 totface = ccgSubSurf_getNumFaces(ss);
1618 for(i = 0; i < totface; i++) {
1619 CCGFace *f = ccgdm->faceMap[i].face;
1620 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1621 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1622 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1623 unsigned char *cp= NULL;
1627 drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1628 mat_nr= faceFlags[origIndex*2 + 1];
1636 flag = drawParams(tf, mcol, mat_nr);
1637 else if (index != ORIGINDEX_NONE)
1638 flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
1640 flag= GPU_enable_material(mat_nr, NULL) ? 1:0;
1643 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
1644 if(tf) tf += gridFaces*gridFaces*numVerts;
1645 if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
1649 /* flag 1 == use vertex colors */
1651 if(flag==1) cp= (unsigned char*)mcol;
1652 mcol += gridFaces*gridFaces*numVerts*4;
1655 for (S=0; S<numVerts; S++) {
1656 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1660 glShadeModel(GL_SMOOTH);
1661 for (y=0; y<gridFaces; y++) {
1662 glBegin(GL_QUAD_STRIP);
1663 for (x=0; x<gridFaces; x++) {
1664 a = &faceGridData[(y+0)*gridSize + x];
1665 b = &faceGridData[(y+1)*gridSize + x];
1667 if(tf) glTexCoord2fv(tf->uv[0]);
1668 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1672 if(tf) glTexCoord2fv(tf->uv[1]);
1673 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1677 if(x != gridFaces-1) {
1683 a = &faceGridData[(y+0)*gridSize + x];
1684 b = &faceGridData[(y+1)*gridSize + x];
1686 if(tf) glTexCoord2fv(tf->uv[3]);
1687 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1691 if(tf) glTexCoord2fv(tf->uv[2]);
1692 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1702 glShadeModel(GL_FLAT);
1704 for (y=0; y<gridFaces; y++) {
1705 for (x=0; x<gridFaces; x++) {
1706 float *a_co = faceGridData[(y+0)*gridSize + x].co;
1707 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
1708 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
1709 float *d_co = faceGridData[(y+1)*gridSize + x].co;
1711 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
1713 if(tf) glTexCoord2fv(tf->uv[1]);
1714 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1717 if(tf) glTexCoord2fv(tf->uv[2]);
1718 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1721 if(tf) glTexCoord2fv(tf->uv[3]);
1722 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1725 if(tf) glTexCoord2fv(tf->uv[0]);
1726 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1739 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
1741 ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
1744 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1746 ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
1749 static void ccgDM_drawUVEdges(DerivedMesh *dm)
1752 MFace *mf = dm->getFaceArray(dm);
1753 MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1758 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
1759 if(!(mf->flag&ME_HIDE)) {
1760 glVertex2fv(tf->uv[0]);
1761 glVertex2fv(tf->uv[1]);
1763 glVertex2fv(tf->uv[1]);
1764 glVertex2fv(tf->uv[2]);
1767 glVertex2fv(tf->uv[2]);
1768 glVertex2fv(tf->uv[0]);
1770 glVertex2fv(tf->uv[2]);
1771 glVertex2fv(tf->uv[3]);
1773 glVertex2fv(tf->uv[3]);
1774 glVertex2fv(tf->uv[0]);
1782 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
1783 int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) {
1784 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1785 CCGSubSurf *ss = ccgdm->ss;
1787 int i, gridSize = ccgSubSurf_getGridSize(ss);
1788 char *faceFlags = ccgdm->faceFlags;
1789 int gridFaces = gridSize - 1, totface;
1791 /* currently unused -- each original face is handled separately */
1792 (void)compareDrawOptions;
1795 mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
1797 mcol = dm->getFaceDataArray(dm, CD_MCOL);
1800 totface = ccgSubSurf_getNumFaces(ss);
1801 for(i = 0; i < totface; i++) {
1802 CCGFace *f = ccgdm->faceMap[i].face;
1803 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1804 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1806 unsigned char *cp= NULL;
1808 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1810 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1811 else drawSmooth = 1;
1814 cp= (unsigned char*)mcol;
1815 mcol += gridFaces*gridFaces*numVerts*4;
1821 if(index == ORIGINDEX_NONE)
1822 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */
1823 else if (setDrawOptions)
1824 draw= setDrawOptions(userData, index, &drawSmooth);
1828 glEnable(GL_POLYGON_STIPPLE);
1829 glPolygonStipple(stipple_quarttone);
1832 for (S=0; S<numVerts; S++) {
1833 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1835 glShadeModel(GL_SMOOTH);
1836 for (y=0; y<gridFaces; y++) {
1838 glBegin(GL_QUAD_STRIP);
1839 for (x=0; x<gridFaces; x++) {
1840 a = &faceGridData[(y+0)*gridSize + x];
1841 b = &faceGridData[(y+1)*gridSize + x];
1843 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1846 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1850 if(x != gridFaces-1) {
1855 a = &faceGridData[(y+0)*gridSize + x];
1856 b = &faceGridData[(y+1)*gridSize + x];
1858 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1861 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1870 glShadeModel(GL_FLAT);
1872 for (y=0; y<gridFaces; y++) {
1873 for (x=0; x<gridFaces; x++) {
1874 float *a = faceGridData[(y+0)*gridSize + x].co;
1875 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1876 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1877 float *d = faceGridData[(y+1)*gridSize + x].co;
1879 ccgDM_glNormalFast(a, b, c, d);
1881 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1883 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1885 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1887 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1897 glDisable(GL_POLYGON_STIPPLE);
1902 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
1903 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1904 CCGSubSurf *ss = ccgdm->ss;
1905 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1906 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1908 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1910 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1911 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1912 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1913 int index = ccgDM_getEdgeMapIndex(ss, e);
1915 glBegin(GL_LINE_STRIP);
1916 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1917 if (useAging && !(G.f&G_BACKBUFSEL)) {
1918 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1919 glColor3ub(0, ageCol>0?ageCol:0, 0);
1922 for (i=0; i<edgeSize-1; i++) {
1923 glVertex3fv(edgeData[i].co);
1924 glVertex3fv(edgeData[i+1].co);
1930 ccgEdgeIterator_free(ei);
1932 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
1933 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1934 CCGSubSurf *ss = ccgdm->ss;
1935 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1936 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1938 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1940 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1941 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1942 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1943 int index = ccgDM_getEdgeMapIndex(ss, e);
1945 glBegin(GL_LINE_STRIP);
1946 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1947 for (i=0; i<edgeSize; i++) {
1948 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
1950 if (useAging && !(G.f&G_BACKBUFSEL)) {
1951 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1952 glColor3ub(0, ageCol>0?ageCol:0, 0);
1955 glVertex3fv(edgeData[i].co);
1961 ccgEdgeIterator_free(ei);
1963 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
1964 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1965 CCGSubSurf *ss = ccgdm->ss;
1966 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1968 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1969 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1970 int index = ccgDM_getFaceMapIndex(ss, f);
1973 /* Face center data normal isn't updated atm. */
1974 DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
1976 func(userData, index, vd->co, vd->no);
1980 ccgFaceIterator_free(fi);
1983 static void ccgDM_release(DerivedMesh *dm) {
1984 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1986 if (DM_release(dm)) {
1987 /* Before freeing, need to update the displacement map */
1988 if(ccgdm->multires.modified) {
1989 /* Check that mmd still exists */
1990 if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
1991 ccgdm->multires.mmd = NULL;
1992 if(ccgdm->multires.mmd)
1993 ccgdm->multires.update(dm);
1996 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
1997 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
1998 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
1999 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2000 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2001 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2002 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2003 MEM_freeN(ccgdm->edgeFlags);
2004 MEM_freeN(ccgdm->faceFlags);
2005 MEM_freeN(ccgdm->vertMap);
2006 MEM_freeN(ccgdm->edgeMap);
2007 MEM_freeN(ccgdm->faceMap);
2012 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2014 if(type == CD_ORIGINDEX) {
2015 /* create origindex on demand to save memory */
2016 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2017 CCGSubSurf *ss= ccgdm->ss;
2019 int a, index, totnone, totorig;
2021 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2022 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2024 totorig = ccgSubSurf_getNumVerts(ss);
2025 totnone= dm->numVertData - totorig;
2027 /* original vertices are at the end */
2028 for(a=0; a<totnone; a++)
2029 origindex[a]= ORIGINDEX_NONE;
2031 for(index=0; index<totorig; index++, a++) {
2032 CCGVert *v = ccgdm->vertMap[index].vert;
2033 origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
2039 return DM_get_vert_data_layer(dm, type);
2042 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2044 if(type == CD_ORIGINDEX) {
2045 /* create origindex on demand to save memory */
2046 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2047 CCGSubSurf *ss= ccgdm->ss;
2049 int a, i, index, totnone, totorig, totedge;
2050 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2052 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2053 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2055 totedge= ccgSubSurf_getNumEdges(ss);
2056 totorig= totedge*(edgeSize - 1);
2057 totnone= dm->numEdgeData - totorig;
2059 /* original edges are at the end */
2060 for(a=0; a<totnone; a++)
2061 origindex[a]= ORIGINDEX_NONE;
2063 for(index=0; index<totedge; index++) {
2064 CCGEdge *e= ccgdm->edgeMap[index].edge;
2065 int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2067 for(i = 0; i < edgeSize - 1; i++, a++)
2068 origindex[a]= mapIndex;
2074 return DM_get_edge_data_layer(dm, type);
2077 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2079 if(type == CD_ORIGINDEX) {
2080 /* create origindex on demand to save memory */
2081 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2082 CCGSubSurf *ss= ccgdm->ss;
2084 int a, i, index, totface;
2085 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2087 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2088 origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
2090 totface= ccgSubSurf_getNumFaces(ss);
2092 for(a=0, index=0; index<totface; index++) {
2093 CCGFace *f = ccgdm->faceMap[index].face;
2094 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2095 int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2097 for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2098 origindex[a]= mapIndex;
2104 return DM_get_face_data_layer(dm, type);
2107 static int ccgDM_getNumGrids(DerivedMesh *dm)
2109 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2110 int index, numFaces, numGrids;
2112 numFaces= ccgSubSurf_getNumFaces(ccgdm->ss);
2115 for(index=0; index<numFaces; index++) {
2116 CCGFace *f = ccgdm->faceMap[index].face;
2117 numGrids += ccgSubSurf_getFaceNumVerts(f);
2123 static int ccgDM_getGridSize(DerivedMesh *dm)
2125 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2126 return ccgSubSurf_getGridSize(ccgdm->ss);
2129 static int ccgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2133 int i, j= 0, numFaces, fIndex, numEdges= 0;
2135 e = ccgSubSurf_getFaceEdge(ss, f, S);
2136 numFaces = ccgSubSurf_getEdgeNumFaces(e);
2141 for(i = 0; i < numFaces; i++) {
2142 adjf = ccgSubSurf_getEdgeFace(e, i);
2145 numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2146 for(j = 0; j < numEdges; j++)
2147 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2155 fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2157 return gridOffset[fIndex] + (j + offset)%numEdges;
2160 static void ccgdm_create_grids(DerivedMesh *dm)
2162 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2163 CCGSubSurf *ss= ccgdm->ss;
2164 DMGridData **gridData;
2165 DMGridAdjacency *gridAdjacency, *adj;
2166 CCGFace **gridFaces;
2168 int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2173 numGrids = ccgDM_getNumGrids(dm);
2174 numFaces = ccgSubSurf_getNumFaces(ss);
2175 /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/
2177 /* compute offset into grid array for each face */
2178 gridOffset = MEM_mallocN(sizeof(int)*numFaces, "ccgdm.gridOffset");
2180 for(gIndex = 0, index = 0; index < numFaces; index++) {
2181 CCGFace *f = ccgdm->faceMap[index].face;
2182 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2184 gridOffset[index] = gIndex;
2188 /* compute grid data */
2189 gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData");
2190 gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency");
2191 gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces");
2193 for(gIndex = 0, index = 0; index < numFaces; index++) {
2194 CCGFace *f = ccgdm->faceMap[index].face;
2195 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2197 for(S = 0; S < numVerts; S++, gIndex++) {
2198 int prevS = (S - 1 + numVerts) % numVerts;
2199 int nextS = (S + 1 + numVerts) % numVerts;
2201 gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2202 gridFaces[gIndex] = f;
2204 adj = &gridAdjacency[gIndex];
2206 adj->index[0] = gIndex - S + nextS;
2207 adj->rotation[0] = 3;
2208 adj->index[1] = ccgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2209 adj->rotation[1] = 1;
2210 adj->index[2] = ccgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2211 adj->rotation[2] = 3;
2212 adj->index[3] = gIndex - S + prevS;
2213 adj->rotation[3] = 1;
2217 ccgdm->gridData = gridData;
2218 ccgdm->gridFaces = gridFaces;
2219 ccgdm->gridAdjacency = gridAdjacency;
2220 ccgdm->gridOffset = gridOffset;
2223 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2225 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2227 ccgdm_create_grids(dm);
2228 return ccgdm->gridData;
2231 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2233 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2235 ccgdm_create_grids(dm);
2236 return ccgdm->gridAdjacency;
2239 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2241 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2243 ccgdm_create_grids(dm);
2244 return ccgdm->gridOffset;
2247 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2249 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2251 if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2254 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2255 me->totvert, me->totface);
2261 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2263 MultiresModifierData *mmd= ccgdm->multires.mmd;
2265 /* both of multires and subsurm modifiers are CCG, but
2266 grids should only be used when sculpting on multires */
2273 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2275 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2276 int gridSize, numGrids, grid_pbvh;
2286 grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2288 if(ob->sculpt->pbvh) {
2290 /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2291 but this can be freed on ccgdm release, this updates the pointers
2292 when the ccgdm gets remade, the assumption is that the topology
2294 ccgdm_create_grids(dm);
2295 BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2298 ccgdm->pbvh = ob->sculpt->pbvh;
2304 /* no pbvh exists yet, we need to create one. only in case of multires
2305 we build a pbvh over the modified mesh, in other cases the base mesh
2306 is being sculpted, so we build a pbvh from that. */
2308 ccgdm_create_grids(dm);
2310 gridSize = ccgDM_getGridSize(dm);
2311 numGrids = ccgDM_getNumGrids(dm);
2313 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2314 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2315 numGrids, gridSize, (void**)ccgdm->gridFaces);
2316 } else if(ob->type == OB_MESH) {
2318 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2319 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2320 me->totface, me->totvert);
2326 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2327 int drawInteriorEdges,
2331 CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2332 CCGVertIterator *vi;
2333 CCGEdgeIterator *ei;
2334 CCGFaceIterator *fi;
2335 int index, totvert, totedge, totface;
2337 int vertNum, edgeNum, faceNum;
2343 /*int gridSideVerts;*/
2345 int gridInternalEdges;
2346 MEdge *medge = NULL;
2347 MFace *mface = NULL;
2349 FaceVertWeight *qweight, *tweight;
2351 DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2352 ccgSubSurf_getNumFinalVerts(ss),
2353 ccgSubSurf_getNumFinalEdges(ss),
2354 ccgSubSurf_getNumFinalFaces(ss));
2356 ccgdm->dm.getMinMax = ccgDM_getMinMax;
2357 ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
2358 ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
2360 ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
2361 ccgdm->dm.getVert = ccgDM_getFinalVert;
2362 ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2363 ccgdm->dm.getFace = ccgDM_getFinalFace;
2364 ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2365 ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2366 ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2367 ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2368 ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
2369 ccgdm->dm.getVertData = DM_get_vert_data;
2370 ccgdm->dm.getEdgeData = DM_get_edge_data;
2371 ccgdm->dm.getFaceData = DM_get_face_data;
2372 ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2373 ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2374 ccgdm->dm.getFaceDataArray = ccgDM_get_face_data_layer;
2375 ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2376 ccgdm->dm.getGridSize = ccgDM_getGridSize;
2377 ccgdm->dm.getGridData = ccgDM_getGridData;
2378 ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2379 ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2380 ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2381 ccgdm->dm.getPBVH = ccgDM_getPBVH;
2383 ccgdm->dm.getVertCos = ccgdm_getVertCos;
2384 ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
2385 ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
2386 ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
2388 ccgdm->dm.drawVerts = ccgDM_drawVerts;
2389 ccgdm->dm.drawEdges = ccgDM_drawEdges;
2390 ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2391 ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2392 ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
2393 ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
2394 ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
2395 ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2396 ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
2397 ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
2398 ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
2400 ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
2401 ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
2403 ccgdm->dm.release = ccgDM_release;
2406 ccgdm->drawInteriorEdges = drawInteriorEdges;
2407 ccgdm->useSubsurfUv = useSubsurfUv;
2409 totvert = ccgSubSurf_getNumVerts(ss);
2410 ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2411 vi = ccgSubSurf_getVertIterator(ss);
2412 for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2413 CCGVert *v = ccgVertIterator_getCurrent(vi);
2415 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2417 ccgVertIterator_free(vi);
2419 totedge = ccgSubSurf_getNumEdges(ss);
2420 ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2421 ei = ccgSubSurf_getEdgeIterator(ss);
2422 for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2423 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2425 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2428 totface = ccgSubSurf_getNumFaces(ss);
2429 ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2430 fi = ccgSubSurf_getFaceIterator(ss);
2431 for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2432 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2434 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2436 ccgFaceIterator_free(fi);
2438 edgeSize = ccgSubSurf_getEdgeSize(ss);
2439 gridSize = ccgSubSurf_getGridSize(ss);
2440 gridFaces = gridSize - 1;
2441 /*gridSideVerts = gridSize - 2;*/ /*UNUSED*/
2442 /*gridInternalVerts = gridSideVerts * gridSideVerts; */ /*UNUSED*/
2443 gridSideEdges = gridSize - 1;
2444 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
2446 calc_ss_weights(gridFaces, &qweight, &tweight);
2452 /* mvert = dm->getVertArray(dm); - as yet unused */
2453 medge = dm->getEdgeArray(dm);
2454 mface = dm->getFaceArray(dm);
2456 faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
2458 orig_indices = (int*)ccgdm->dm.getFaceDataArray(&ccgdm->dm, CD_ORIGINDEX);
2459 for(index = 0; index < totface; ++index) {
2460 CCGFace *f = ccgdm->faceMap[index].face;
2461 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2462 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2463 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2464 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
2468 ccgdm->faceMap[index].startVert = vertNum;
2469 ccgdm->faceMap[index].startEdge = edgeNum;
2470 ccgdm->faceMap[index].startFace = faceNum;
2473 orig_indices[faceNum] = origIndex;
2475 /* set the face base vert */
2476 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2478 for(S = 0; S < numVerts; S++) {
2479 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
2481 vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2484 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
2488 for(S = 0; S < numVerts; S++) {
2489 int prevS = (S - 1 + numVerts) % numVerts;
2490 int nextS = (S + 1) % numVerts;
2491 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2492 for(x = 1; x < gridFaces; x++) {
2494 w[prevS] = weight[x][0][0];
2495 w[S] = weight[x][0][1];
2496 w[nextS] = weight[x][0][2];
2497 w[otherS] = weight[x][0][3];
2498 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2504 for(S = 0; S < numVerts; S++) {
2505 int prevS = (S - 1 + numVerts) % numVerts;
2506 int nextS = (S + 1) % numVerts;
2507 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2508 for(y = 1; y < gridFaces; y++) {
2509 for(x = 1; x < gridFaces; x++) {
2511 w[prevS] = weight[y * gridFaces + x][0][0];
2512 w[S] = weight[y * gridFaces + x][0][1];
2513 w[nextS] = weight[y * gridFaces + x][0][2];
2514 w[otherS] = weight[y * gridFaces + x][0][3];
2515 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2522 for(S = 0; S < numVerts; S++) {
2523 int prevS = (S - 1 + numVerts) % numVerts;
2524 int nextS = (S + 1) % numVerts;
2525 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2527 weight = (numVerts == 4) ? qweight : tweight;
2529 for(y = 0; y < gridFaces; y++) {
2530 for(x = 0; x < gridFaces; x++) {
2534 for(j = 0; j < 4; ++j) {
2535 w[j][prevS] = (*weight)[j][0];
2536 w[j][S] = (*weight)[j][1];
2537 w[j][nextS] = (*weight)[j][2];
2538 w[j][otherS] = (*weight)[j][3];
2541 DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
2550 faceFlags[index*2] = mface[origIndex].flag;
2551 faceFlags[index*2 + 1] = mface[origIndex].mat_nr;
2553 edgeNum += numFinalEdges;
2557 CustomData *fdata = &ccgdm->dm.faceData;
2558 CustomData *dmfdata = &dm->faceData;
2559 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
2560 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
2562 for (i=0; i<numlayer && i<dmnumlayer; i++)
2563 set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2566 edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "edgeFlags");
2568 for(index = 0; index < totedge; ++index) {
2569 CCGEdge *e = ccgdm->edgeMap[index].edge;
2570 int numFinalEdges = edgeSize - 1;
2573 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
2576 v = ccgSubSurf_getEdgeVert0(e);
2577 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2578 v = ccgSubSurf_getEdgeVert1(e);
2579 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2581 ccgdm->edgeMap[index].startVert = vertNum;
2582 ccgdm->edgeMap[index].startEdge = edgeNum;
2584 /* set the edge base vert */
2585 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2587 for(x = 1; x < edgeSize - 1; x++) {
2589 w[1] = (float) x / (edgeSize - 1);
2591 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2595 edgeFlags[index]= medge[edgeIdx].flag;
2597 edgeNum += numFinalEdges;
2600 for(index = 0; index < totvert; ++index) {
2601 CCGVert *v = ccgdm->vertMap[index].vert;
2604 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2606 ccgdm->vertMap[index].startVert = vertNum;
2608 /* set the vert base vert */
2609 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2611 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2624 struct DerivedMesh *subsurf_make_derived_from_derived(
2625 struct DerivedMesh *dm,
2626 struct SubsurfModifierData *smd,
2627 int useRenderParams, float (*vertCos)[3],
2628 int isFinalCalc, int forEditMode, int inEditMode)
2630 int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
2631 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2632 int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
2633 int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2634 CCGDerivedMesh *result;
2637 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2639 smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0,
2641 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
2643 result = getCCGDerivedMesh(smd->emCache,
2646 } else if(useRenderParams) {
2647 /* Do not use cache in render mode. */
2649 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->renderLevels): smd->renderLevels;
2654 ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2656 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2658 result = getCCGDerivedMesh(ss,
2659 drawInteriorEdges, useSubsurfUv, dm);
2663 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2664 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2665 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2668 /* It is quite possible there is a much better place to do this. It
2669 * depends a bit on how rigourously we expect this function to never
2670 * be called in editmode. In semi-theory we could share a single
2671 * cache, but the handles used inside and outside editmode are not
2672 * the same so we would need some way of converting them. Its probably
2673 * not worth the effort. But then why am I even writing this long
2674 * comment that no one will read? Hmmm. - zr
2676 * Addendum: we can't really ensure that this is never called in edit
2677 * mode, so now we have a parameter to verify it. - brecht
2679 if(!inEditMode && smd->emCache) {
2680 ccgSubSurf_free(smd->emCache);
2681 smd->emCache = NULL;
2684 if(useIncremental && isFinalCalc) {
2685 smd->mCache = ss = _getSubSurf(smd->mCache, levels,
2686 useAging, 0, useSimple);
2688 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2690 result = getCCGDerivedMesh(smd->mCache,
2694 if (smd->mCache && isFinalCalc) {
2695 ccgSubSurf_free(smd->mCache);
2699 ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2700 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2702 result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2711 return (DerivedMesh*)result;
2714 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
2716 /* Finds the subsurf limit positions for the verts in a mesh
2717 * and puts them in an array of floats. Please note that the
2718 * calculated vert positions is incorrect for the verts
2719 * on the boundary of the mesh.
2721 CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
2722 float edge_sum[3], face_sum[3];
2723 CCGVertIterator *vi;
2724 DerivedMesh *dm = CDDM_from_mesh(me, NULL);
2726 ss_sync_from_derivedmesh(ss, dm, NULL, 0);
2728 vi = ccgSubSurf_getVertIterator(ss);
2729 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2730 CCGVert *v = ccgVertIterator_getCurrent(vi);
2731 int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2732 int N = ccgSubSurf_getVertNumEdges(v);
2733 int numFaces = ccgSubSurf_getVertNumFaces(v);
2737 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
2738 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
2740 for (i=0; i<N; i++) {
2741 CCGEdge *e = ccgSubSurf_getVertEdge(v, i);
2742 add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2744 for (i=0; i<numFaces; i++) {
2745 CCGFace *f = ccgSubSurf_getVertFace(v, i);
2746 add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
2749 /* ad-hoc correction for boundary vertices, to at least avoid them
2750 moving completely out of place (brecht) */
2751 if(numFaces && numFaces != N)
2752 mul_v3_fl(face_sum, (float)N/(float)numFaces);
2754 co = ccgSubSurf_getVertData(ss, v);
2755 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
2756 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
2757 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
2759 ccgVertIterator_free(vi);
2761 ccgSubSurf_free(ss);