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"
67 #include "GPU_extensions.h"
68 #include "GPU_material.h"
70 #include "CCGSubSurf.h"
72 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
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, offsetof(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 /* keep types in sync with MFace, avoid many conversions */
972 char flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
973 short mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
975 for(S = 0; S < numVerts; S++) {
976 for(y = 0; y < gridSize - 1; y++) {
977 for(x = 0; x < gridSize - 1; x++) {
978 MFace *mf = &mface[i];
979 mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
981 mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
983 mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
985 mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
997 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
998 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
999 CCGSubSurf *ss = ccgdm->ss;
1000 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1001 int gridSize = ccgSubSurf_getGridSize(ss);
1003 CCGVertIterator *vi;
1004 CCGEdgeIterator *ei;
1005 CCGFaceIterator *fi;
1009 int index, totvert, totedge, totface;
1011 totvert = ccgSubSurf_getNumVerts(ss);
1012 vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1013 vi = ccgSubSurf_getVertIterator(ss);
1014 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1015 CCGVert *v = ccgVertIterator_getCurrent(vi);
1017 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1019 ccgVertIterator_free(vi);
1021 totedge = ccgSubSurf_getNumEdges(ss);
1022 edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1023 ei = ccgSubSurf_getEdgeIterator(ss);
1024 for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1025 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1027 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1030 totface = ccgSubSurf_getNumFaces(ss);
1031 faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1032 fi = ccgSubSurf_getFaceIterator(ss);
1033 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1034 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1036 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
1038 ccgFaceIterator_free(fi);
1041 for (index=0; index<totface; index++) {
1042 CCGFace *f = faceMap2[index];
1043 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1045 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
1047 for (S=0; S<numVerts; S++) {
1048 for (x=1; x<gridSize-1; x++) {
1049 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1053 for (S=0; S<numVerts; S++) {
1054 for (y=1; y<gridSize-1; y++) {
1055 for (x=1; x<gridSize-1; x++) {
1056 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1062 for (index=0; index<totedge; index++) {
1063 CCGEdge *e= edgeMap2[index];
1066 for (x=1; x<edgeSize-1; x++) {
1067 copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1071 for (index=0; index<totvert; index++) {
1072 CCGVert *v = vertMap2[index];
1073 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
1076 MEM_freeN(vertMap2);
1077 MEM_freeN(edgeMap2);
1078 MEM_freeN(faceMap2);
1080 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1081 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1082 CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
1084 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1085 CCGVert *v = ccgVertIterator_getCurrent(vi);
1086 DMGridData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1087 int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
1090 func(userData, index, vd->co, vd->no, NULL);
1093 ccgVertIterator_free(vi);
1095 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1096 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1097 CCGSubSurf *ss = ccgdm->ss;
1098 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1099 int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1101 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1102 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1103 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1104 int index = ccgDM_getEdgeMapIndex(ss, e);
1107 for (i=0; i<edgeSize-1; i++)
1108 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1112 ccgEdgeIterator_free(ei);
1115 static void ccgDM_drawVerts(DerivedMesh *dm) {
1116 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1117 CCGSubSurf *ss = ccgdm->ss;
1118 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1119 int gridSize = ccgSubSurf_getGridSize(ss);
1120 CCGVertIterator *vi;
1121 CCGEdgeIterator *ei;
1122 CCGFaceIterator *fi;
1125 vi = ccgSubSurf_getVertIterator(ss);
1126 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1127 CCGVert *v = ccgVertIterator_getCurrent(vi);
1128 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1130 ccgVertIterator_free(vi);
1132 ei = ccgSubSurf_getEdgeIterator(ss);
1133 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1134 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1137 for (x=1; x<edgeSize-1; x++)
1138 glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1140 ccgEdgeIterator_free(ei);
1142 fi = ccgSubSurf_getFaceIterator(ss);
1143 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1144 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1145 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1147 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1148 for (S=0; S<numVerts; S++)
1149 for (x=1; x<gridSize-1; x++)
1150 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1151 for (S=0; S<numVerts; S++)
1152 for (y=1; y<gridSize-1; y++)
1153 for (x=1; x<gridSize-1; x++)
1154 glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1156 ccgFaceIterator_free(fi);
1160 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
1162 if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
1166 BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void***)&faces, &totface);
1168 ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
1169 ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
1175 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(drawAllEdges)) {
1176 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1177 CCGSubSurf *ss = ccgdm->ss;
1178 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1179 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1180 int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1181 int totedge = ccgSubSurf_getNumEdges(ss);
1182 int gridSize = ccgSubSurf_getGridSize(ss);
1185 ccgdm_pbvh_update(ccgdm);
1187 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1189 for (j=0; j< totedge; j++) {
1190 CCGEdge *e = ccgdm->edgeMap[j].edge;
1191 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1193 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1196 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1199 if (useAging && !(G.f&G_BACKBUFSEL)) {
1200 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1201 glColor3ub(0, ageCol>0?ageCol:0, 0);
1204 glBegin(GL_LINE_STRIP);
1205 for (i=0; i<edgeSize-1; i++) {
1206 glVertex3fv(edgeData[i].co);
1207 glVertex3fv(edgeData[i+1].co);
1212 if (useAging && !(G.f&G_BACKBUFSEL)) {
1213 glColor3ub(0, 0, 0);
1216 if (ccgdm->drawInteriorEdges) {
1217 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1218 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1219 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1221 for (S=0; S<numVerts; S++) {
1222 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1224 glBegin(GL_LINE_STRIP);
1225 for (x=0; x<gridSize; x++)
1226 glVertex3fv(faceGridData[x].co);
1228 for (y=1; y<gridSize-1; y++) {
1229 glBegin(GL_LINE_STRIP);
1230 for (x=0; x<gridSize; x++)
1231 glVertex3fv(faceGridData[y*gridSize + x].co);
1234 for (x=1; x<gridSize-1; x++) {
1235 glBegin(GL_LINE_STRIP);
1236 for (y=0; y<gridSize; y++)
1237 glVertex3fv(faceGridData[y*gridSize + x].co);
1244 ccgFaceIterator_free(fi);
1245 ccgEdgeIterator_free(ei);
1247 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1248 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1249 CCGSubSurf *ss = ccgdm->ss;
1250 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1251 int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1253 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1254 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1255 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1257 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1258 glBegin(GL_LINE_STRIP);
1259 for (i=0; i<edgeSize-1; i++) {
1260 glVertex3fv(edgeData[i].co);
1261 glVertex3fv(edgeData[i+1].co);
1267 ccgEdgeIterator_free(ei);
1270 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1272 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1273 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1276 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1277 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1278 no[2] = b_dX*a_cY - b_dY*a_cX;
1280 /* don't normalize, GL_NORMALIZE is enabled */
1284 /* Only used by non-editmesh types */
1285 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
1286 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1287 CCGSubSurf *ss = ccgdm->ss;
1288 CCGFaceIterator *fi;
1289 int gridSize = ccgSubSurf_getGridSize(ss);
1290 char *faceFlags = ccgdm->faceFlags;
1291 int step = (fast)? gridSize-1: 1;
1293 ccgdm_pbvh_update(ccgdm);
1295 if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1296 if(dm->numFaceData) {
1297 /* should be per face */
1298 if(!setMaterial(faceFlags[1]+1, NULL))
1301 glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
1302 BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH));
1303 glShadeModel(GL_FLAT);
1309 fi = ccgSubSurf_getFaceIterator(ss);
1310 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1311 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1312 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1313 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1314 int drawSmooth, mat_nr;
1317 drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1318 mat_nr= faceFlags[index*2 + 1];
1325 if (!setMaterial(mat_nr+1, NULL))
1328 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1329 for (S=0; S<numVerts; S++) {
1330 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1333 for (y=0; y<gridSize-1; y+=step) {
1334 glBegin(GL_QUAD_STRIP);
1335 for (x=0; x<gridSize; x+=step) {
1336 DMGridData *a = &faceGridData[(y+0)*gridSize + x];
1337 DMGridData *b = &faceGridData[(y+step)*gridSize + x];
1348 for (y=0; y<gridSize-1; y+=step) {
1349 for (x=0; x<gridSize-1; x+=step) {
1350 float *a = faceGridData[(y+0)*gridSize + x].co;
1351 float *b = faceGridData[(y+0)*gridSize + x + step].co;
1352 float *c = faceGridData[(y+step)*gridSize + x + step].co;
1353 float *d = faceGridData[(y+step)*gridSize + x].co;
1355 ccgDM_glNormalFast(a, b, c, d);
1368 ccgFaceIterator_free(fi);
1371 /* Only used by non-editmesh types */
1372 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
1373 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1374 CCGSubSurf *ss = ccgdm->ss;
1375 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1376 GPUVertexAttribs gattribs;
1377 DMVertexAttribs attribs= {{{NULL}}};
1378 /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1379 int gridSize = ccgSubSurf_getGridSize(ss);
1380 int gridFaces = gridSize - 1;
1381 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1382 char *faceFlags = ccgdm->faceFlags;
1383 int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
1385 ccgdm_pbvh_update(ccgdm);
1390 #define PASSATTRIB(dx, dy, vert) { \
1391 if(attribs.totorco) { \
1392 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize); \
1393 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \
1395 for(b = 0; b < attribs.tottface; b++) { \
1396 MTFace *tf = &attribs.tface[b].array[a]; \
1397 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \
1399 for(b = 0; b < attribs.totmcol; b++) { \
1400 MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \
1402 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
1403 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
1405 if(attribs.tottang) { \
1406 float *tang = attribs.tang.array[a*4 + vert]; \
1407 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \
1411 totface = ccgSubSurf_getNumFaces(ss);
1412 for(a = 0, i = 0; i < totface; i++) {
1413 CCGFace *f = ccgdm->faceMap[i].face;
1414 int S, x, y, drawSmooth;
1415 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1416 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1418 numVerts = ccgSubSurf_getFaceNumVerts(f);
1421 drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1422 new_matnr= faceFlags[index*2 + 1] + 1;
1429 if(new_matnr != matnr) {
1430 doDraw = setMaterial(matnr = new_matnr, &gattribs);
1432 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1435 if(!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && !setDrawOptions(userData, origIndex))) {
1436 a += gridFaces*gridFaces*numVerts;
1440 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1441 for (S=0; S<numVerts; S++) {
1442 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1443 DMGridData *vda, *vdb;
1446 for (y=0; y<gridFaces; y++) {
1447 glBegin(GL_QUAD_STRIP);
1448 for (x=0; x<gridFaces; x++) {
1449 vda = &faceGridData[(y+0)*gridSize + x];
1450 vdb = &faceGridData[(y+1)*gridSize + x];
1452 PASSATTRIB(0, 0, 0);
1453 glNormal3fv(vda->no);
1454 glVertex3fv(vda->co);
1456 PASSATTRIB(0, 1, 1);
1457 glNormal3fv(vdb->no);
1458 glVertex3fv(vdb->co);
1460 if(x != gridFaces-1)
1464 vda = &faceGridData[(y+0)*gridSize + x];
1465 vdb = &faceGridData[(y+1)*gridSize + x];
1467 PASSATTRIB(0, 0, 3);
1468 glNormal3fv(vda->no);
1469 glVertex3fv(vda->co);
1471 PASSATTRIB(0, 1, 2);
1472 glNormal3fv(vdb->no);
1473 glVertex3fv(vdb->co);
1481 for (y=0; y<gridFaces; y++) {
1482 for (x=0; x<gridFaces; x++) {
1483 float *aco = faceGridData[(y+0)*gridSize + x].co;
1484 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1485 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1486 float *dco = faceGridData[(y+1)*gridSize + x].co;
1488 ccgDM_glNormalFast(aco, bco, cco, dco);
1490 PASSATTRIB(0, 1, 1);
1492 PASSATTRIB(1, 1, 2);
1494 PASSATTRIB(1, 0, 3);
1496 PASSATTRIB(0, 0, 0);
1509 ccgFaceIterator_free(fi);
1512 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1513 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1516 /* Only used by non-editmesh types */
1517 static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData) {
1518 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1519 CCGSubSurf *ss = ccgdm->ss;
1520 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1521 GPUVertexAttribs gattribs;
1522 DMVertexAttribs attribs= {{{NULL}}};
1523 int gridSize = ccgSubSurf_getGridSize(ss);
1524 int gridFaces = gridSize - 1;
1525 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1526 char *faceFlags = ccgdm->faceFlags;
1527 int a, b, i, numVerts, matnr, new_matnr, totface;
1529 ccgdm_pbvh_update(ccgdm);
1533 #define PASSATTRIB(dx, dy, vert) { \
1534 if(attribs.totorco) { \
1535 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize); \
1536 if(attribs.orco.glTexco) \
1537 glTexCoord3fv(attribs.orco.array[index]); \
1539 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \
1541 for(b = 0; b < attribs.tottface; b++) { \
1542 MTFace *tf = &attribs.tface[b].array[a]; \
1543 if(attribs.tface[b].glTexco) \
1544 glTexCoord2fv(tf->uv[vert]); \
1546 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \
1548 for(b = 0; b < attribs.totmcol; b++) { \
1549 MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \
1551 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
1552 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
1554 if(attribs.tottang) { \
1555 float *tang = attribs.tang.array[a*4 + vert]; \
1556 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \
1560 totface = ccgSubSurf_getNumFaces(ss);
1561 for(a = 0, i = 0; i < totface; i++) {
1562 CCGFace *f = ccgdm->faceMap[i].face;
1563 int S, x, y, drawSmooth;
1564 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1565 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1567 numVerts = ccgSubSurf_getFaceNumVerts(f);
1571 drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1572 new_matnr= faceFlags[index*2 + 1] + 1;
1580 if(new_matnr != matnr) {
1581 setMaterial(userData, matnr = new_matnr, &gattribs);
1582 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1586 if((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) {
1587 a += gridFaces*gridFaces*numVerts;
1592 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1593 for (S=0; S<numVerts; S++) {
1594 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1595 DMGridData *vda, *vdb;
1598 for (y=0; y<gridFaces; y++) {
1599 glBegin(GL_QUAD_STRIP);
1600 for (x=0; x<gridFaces; x++) {
1601 vda = &faceGridData[(y+0)*gridSize + x];
1602 vdb = &faceGridData[(y+1)*gridSize + x];
1604 PASSATTRIB(0, 0, 0);
1605 glNormal3fv(vda->no);
1606 glVertex3fv(vda->co);
1608 PASSATTRIB(0, 1, 1);
1609 glNormal3fv(vdb->no);
1610 glVertex3fv(vdb->co);
1612 if(x != gridFaces-1)
1616 vda = &faceGridData[(y+0)*gridSize + x];
1617 vdb = &faceGridData[(y+1)*gridSize + x];
1619 PASSATTRIB(0, 0, 3);
1620 glNormal3fv(vda->no);
1621 glVertex3fv(vda->co);
1623 PASSATTRIB(0, 1, 2);
1624 glNormal3fv(vdb->no);
1625 glVertex3fv(vdb->co);
1633 for (y=0; y<gridFaces; y++) {
1634 for (x=0; x<gridFaces; x++) {
1635 float *aco = faceGridData[(y+0)*gridSize + x].co;
1636 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1637 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1638 float *dco = faceGridData[(y+1)*gridSize + x].co;
1640 ccgDM_glNormalFast(aco, bco, cco, dco);
1642 PASSATTRIB(0, 1, 1);
1644 PASSATTRIB(1, 1, 2);
1646 PASSATTRIB(1, 0, 3);
1648 PASSATTRIB(0, 0, 0);
1661 ccgFaceIterator_free(fi);
1665 static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
1666 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1667 CCGSubSurf *ss = ccgdm->ss;
1668 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1669 int gridSize = ccgSubSurf_getGridSize(ss);
1670 unsigned char *cp1, *cp2;
1673 ccgdm_pbvh_update(ccgdm);
1683 glShadeModel(GL_SMOOTH);
1686 glEnable(GL_CULL_FACE);
1690 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1691 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1692 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1694 for (S=0; S<numVerts; S++) {
1695 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1696 for (y=0; y<gridSize-1; y++) {
1697 for (x=0; x<gridSize-1; x++) {
1698 float *a = faceGridData[(y+0)*gridSize + x].co;
1699 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1700 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1701 float *d = faceGridData[(y+1)*gridSize + x].co;
1703 glColor3ub(cp1[3], cp1[2], cp1[1]);
1705 glColor3ub(cp1[7], cp1[6], cp1[5]);
1707 glColor3ub(cp1[11], cp1[10], cp1[9]);
1709 glColor3ub(cp1[15], cp1[14], cp1[13]);
1713 glColor3ub(cp2[15], cp2[14], cp2[13]);
1715 glColor3ub(cp2[11], cp2[10], cp2[9]);
1717 glColor3ub(cp2[7], cp2[6], cp2[5]);
1719 glColor3ub(cp2[3], cp2[2], cp2[1]);
1731 ccgFaceIterator_free(fi);
1734 static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
1735 int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
1736 int (*drawParamsMapped)(void *userData, int index),
1739 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1740 CCGSubSurf *ss = ccgdm->ss;
1741 MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
1742 MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1743 char *faceFlags = ccgdm->faceFlags;
1744 int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1745 int gridFaces = gridSize - 1;
1747 ccgdm_pbvh_update(ccgdm);
1750 mcol = dm->getFaceDataArray(dm, CD_MCOL);
1752 totface = ccgSubSurf_getNumFaces(ss);
1753 for(i = 0; i < totface; i++) {
1754 CCGFace *f = ccgdm->faceMap[i].face;
1755 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1756 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1757 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1758 unsigned char *cp= NULL;
1762 drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1763 mat_nr= faceFlags[origIndex*2 + 1];
1771 flag = drawParams(tf, (mcol != NULL), mat_nr);
1772 else if (index != ORIGINDEX_NONE)
1773 flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
1775 flag= GPU_enable_material(mat_nr, NULL) ? 1:0;
1778 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
1779 if(tf) tf += gridFaces*gridFaces*numVerts;
1780 if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
1784 /* flag 1 == use vertex colors */
1786 if(flag==1) cp= (unsigned char*)mcol;
1787 mcol += gridFaces*gridFaces*numVerts*4;
1790 for (S=0; S<numVerts; S++) {
1791 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1795 glShadeModel(GL_SMOOTH);
1796 for (y=0; y<gridFaces; y++) {
1797 glBegin(GL_QUAD_STRIP);
1798 for (x=0; x<gridFaces; x++) {
1799 a = &faceGridData[(y+0)*gridSize + x];
1800 b = &faceGridData[(y+1)*gridSize + x];
1802 if(tf) glTexCoord2fv(tf->uv[0]);
1803 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1807 if(tf) glTexCoord2fv(tf->uv[1]);
1808 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1812 if(x != gridFaces-1) {
1818 a = &faceGridData[(y+0)*gridSize + x];
1819 b = &faceGridData[(y+1)*gridSize + x];
1821 if(tf) glTexCoord2fv(tf->uv[3]);
1822 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1826 if(tf) glTexCoord2fv(tf->uv[2]);
1827 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1837 glShadeModel(GL_FLAT);
1839 for (y=0; y<gridFaces; y++) {
1840 for (x=0; x<gridFaces; x++) {
1841 float *a_co = faceGridData[(y+0)*gridSize + x].co;
1842 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
1843 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
1844 float *d_co = faceGridData[(y+1)*gridSize + x].co;
1846 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
1848 if(tf) glTexCoord2fv(tf->uv[1]);
1849 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1852 if(tf) glTexCoord2fv(tf->uv[2]);
1853 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1856 if(tf) glTexCoord2fv(tf->uv[3]);
1857 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1860 if(tf) glTexCoord2fv(tf->uv[0]);
1861 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1874 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr))
1876 ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
1879 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1881 ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
1884 static void ccgDM_drawUVEdges(DerivedMesh *dm)
1887 MFace *mf = dm->getFaceArray(dm);
1888 MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1893 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
1894 if(!(mf->flag&ME_HIDE)) {
1895 glVertex2fv(tf->uv[0]);
1896 glVertex2fv(tf->uv[1]);
1898 glVertex2fv(tf->uv[1]);
1899 glVertex2fv(tf->uv[2]);
1902 glVertex2fv(tf->uv[2]);
1903 glVertex2fv(tf->uv[0]);
1905 glVertex2fv(tf->uv[2]);
1906 glVertex2fv(tf->uv[3]);
1908 glVertex2fv(tf->uv[3]);
1909 glVertex2fv(tf->uv[0]);
1917 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
1918 int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) {
1919 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1920 CCGSubSurf *ss = ccgdm->ss;
1922 int i, gridSize = ccgSubSurf_getGridSize(ss);
1923 char *faceFlags = ccgdm->faceFlags;
1924 int gridFaces = gridSize - 1, totface;
1926 /* currently unused -- each original face is handled separately */
1927 (void)compareDrawOptions;
1930 mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
1932 mcol = dm->getFaceDataArray(dm, CD_MCOL);
1935 totface = ccgSubSurf_getNumFaces(ss);
1936 for(i = 0; i < totface; i++) {
1937 CCGFace *f = ccgdm->faceMap[i].face;
1938 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1939 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1941 unsigned char *cp= NULL;
1943 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1945 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1946 else drawSmooth = 1;
1949 cp= (unsigned char*)mcol;
1950 mcol += gridFaces*gridFaces*numVerts*4;
1956 if(index == ORIGINDEX_NONE)
1957 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */
1958 else if (setDrawOptions)
1959 draw= setDrawOptions(userData, index, &drawSmooth);
1963 glEnable(GL_POLYGON_STIPPLE);
1964 glPolygonStipple(stipple_quarttone);
1967 for (S=0; S<numVerts; S++) {
1968 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1970 glShadeModel(GL_SMOOTH);
1971 for (y=0; y<gridFaces; y++) {
1973 glBegin(GL_QUAD_STRIP);
1974 for (x=0; x<gridFaces; x++) {
1975 a = &faceGridData[(y+0)*gridSize + x];
1976 b = &faceGridData[(y+1)*gridSize + x];
1978 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1981 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1985 if(x != gridFaces-1) {
1990 a = &faceGridData[(y+0)*gridSize + x];
1991 b = &faceGridData[(y+1)*gridSize + x];
1993 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1996 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2005 glShadeModel(GL_FLAT);
2007 for (y=0; y<gridFaces; y++) {
2008 for (x=0; x<gridFaces; x++) {
2009 float *a = faceGridData[(y+0)*gridSize + x].co;
2010 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2011 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2012 float *d = faceGridData[(y+1)*gridSize + x].co;
2014 ccgDM_glNormalFast(a, b, c, d);
2016 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2018 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2020 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2022 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2032 glDisable(GL_POLYGON_STIPPLE);
2037 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2038 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2039 CCGSubSurf *ss = ccgdm->ss;
2040 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2041 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2043 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2045 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2046 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2047 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2048 int index = ccgDM_getEdgeMapIndex(ss, e);
2050 glBegin(GL_LINE_STRIP);
2051 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2052 if (useAging && !(G.f&G_BACKBUFSEL)) {
2053 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2054 glColor3ub(0, ageCol>0?ageCol:0, 0);
2057 for (i=0; i<edgeSize-1; i++) {
2058 glVertex3fv(edgeData[i].co);
2059 glVertex3fv(edgeData[i+1].co);
2065 ccgEdgeIterator_free(ei);
2067 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2068 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2069 CCGSubSurf *ss = ccgdm->ss;
2070 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2071 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2073 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2075 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2076 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2077 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2078 int index = ccgDM_getEdgeMapIndex(ss, e);
2080 glBegin(GL_LINE_STRIP);
2081 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2082 for (i=0; i<edgeSize; i++) {
2083 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2085 if (useAging && !(G.f&G_BACKBUFSEL)) {
2086 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2087 glColor3ub(0, ageCol>0?ageCol:0, 0);
2090 glVertex3fv(edgeData[i].co);
2096 ccgEdgeIterator_free(ei);
2098 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2099 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2100 CCGSubSurf *ss = ccgdm->ss;
2101 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2103 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2104 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2105 int index = ccgDM_getFaceMapIndex(ss, f);
2108 /* Face center data normal isn't updated atm. */
2109 DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2111 func(userData, index, vd->co, vd->no);
2115 ccgFaceIterator_free(fi);
2118 static void ccgDM_release(DerivedMesh *dm) {
2119 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2121 if (DM_release(dm)) {
2122 /* Before freeing, need to update the displacement map */
2123 if(ccgdm->multires.modified) {
2124 /* Check that mmd still exists */
2125 if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2126 ccgdm->multires.mmd = NULL;
2127 if(ccgdm->multires.mmd)
2128 ccgdm->multires.update(dm);
2131 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
2132 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
2133 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
2134 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2135 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2136 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2137 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2138 MEM_freeN(ccgdm->edgeFlags);
2139 MEM_freeN(ccgdm->faceFlags);
2140 MEM_freeN(ccgdm->vertMap);
2141 MEM_freeN(ccgdm->edgeMap);
2142 MEM_freeN(ccgdm->faceMap);
2147 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2149 if(type == CD_ORIGINDEX) {
2150 /* create origindex on demand to save memory */
2151 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2152 CCGSubSurf *ss= ccgdm->ss;
2154 int a, index, totnone, totorig;
2156 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2157 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2159 totorig = ccgSubSurf_getNumVerts(ss);
2160 totnone= dm->numVertData - totorig;
2162 /* original vertices are at the end */
2163 for(a=0; a<totnone; a++)
2164 origindex[a]= ORIGINDEX_NONE;
2166 for(index=0; index<totorig; index++, a++) {
2167 CCGVert *v = ccgdm->vertMap[index].vert;
2168 origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
2174 return DM_get_vert_data_layer(dm, type);
2177 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2179 if(type == CD_ORIGINDEX) {
2180 /* create origindex on demand to save memory */
2181 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2182 CCGSubSurf *ss= ccgdm->ss;
2184 int a, i, index, totnone, totorig, totedge;
2185 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2187 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2188 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2190 totedge= ccgSubSurf_getNumEdges(ss);
2191 totorig= totedge*(edgeSize - 1);
2192 totnone= dm->numEdgeData - totorig;
2194 /* original edges are at the end */
2195 for(a=0; a<totnone; a++)
2196 origindex[a]= ORIGINDEX_NONE;
2198 for(index=0; index<totedge; index++) {
2199 CCGEdge *e= ccgdm->edgeMap[index].edge;
2200 int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2202 for(i = 0; i < edgeSize - 1; i++, a++)
2203 origindex[a]= mapIndex;
2209 return DM_get_edge_data_layer(dm, type);
2212 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2214 if(type == CD_ORIGINDEX) {
2215 /* create origindex on demand to save memory */
2216 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2217 CCGSubSurf *ss= ccgdm->ss;
2219 int a, i, index, totface;
2220 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2222 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2223 origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
2225 totface= ccgSubSurf_getNumFaces(ss);
2227 for(a=0, index=0; index<totface; index++) {
2228 CCGFace *f = ccgdm->faceMap[index].face;
2229 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2230 int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2232 for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2233 origindex[a]= mapIndex;
2239 return DM_get_face_data_layer(dm, type);
2242 static int ccgDM_getNumGrids(DerivedMesh *dm)
2244 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2245 int index, numFaces, numGrids;
2247 numFaces= ccgSubSurf_getNumFaces(ccgdm->ss);
2250 for(index=0; index<numFaces; index++) {
2251 CCGFace *f = ccgdm->faceMap[index].face;
2252 numGrids += ccgSubSurf_getFaceNumVerts(f);
2258 static int ccgDM_getGridSize(DerivedMesh *dm)
2260 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2261 return ccgSubSurf_getGridSize(ccgdm->ss);
2264 static int ccgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2268 int i, j= 0, numFaces, fIndex, numEdges= 0;
2270 e = ccgSubSurf_getFaceEdge(ss, f, S);
2271 numFaces = ccgSubSurf_getEdgeNumFaces(e);
2276 for(i = 0; i < numFaces; i++) {
2277 adjf = ccgSubSurf_getEdgeFace(e, i);
2280 numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2281 for(j = 0; j < numEdges; j++)
2282 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2290 fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2292 return gridOffset[fIndex] + (j + offset)%numEdges;
2295 static void ccgdm_create_grids(DerivedMesh *dm)
2297 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2298 CCGSubSurf *ss= ccgdm->ss;
2299 DMGridData **gridData;
2300 DMGridAdjacency *gridAdjacency, *adj;
2301 CCGFace **gridFaces;
2303 int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2308 numGrids = ccgDM_getNumGrids(dm);
2309 numFaces = ccgSubSurf_getNumFaces(ss);
2310 /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/
2312 /* compute offset into grid array for each face */
2313 gridOffset = MEM_mallocN(sizeof(int)*numFaces, "ccgdm.gridOffset");
2315 for(gIndex = 0, index = 0; index < numFaces; index++) {
2316 CCGFace *f = ccgdm->faceMap[index].face;
2317 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2319 gridOffset[index] = gIndex;
2323 /* compute grid data */
2324 gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData");
2325 gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency");
2326 gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces");
2328 for(gIndex = 0, index = 0; index < numFaces; index++) {
2329 CCGFace *f = ccgdm->faceMap[index].face;
2330 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2332 for(S = 0; S < numVerts; S++, gIndex++) {
2333 int prevS = (S - 1 + numVerts) % numVerts;
2334 int nextS = (S + 1 + numVerts) % numVerts;
2336 gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2337 gridFaces[gIndex] = f;
2339 adj = &gridAdjacency[gIndex];
2341 adj->index[0] = gIndex - S + nextS;
2342 adj->rotation[0] = 3;
2343 adj->index[1] = ccgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2344 adj->rotation[1] = 1;
2345 adj->index[2] = ccgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2346 adj->rotation[2] = 3;
2347 adj->index[3] = gIndex - S + prevS;
2348 adj->rotation[3] = 1;
2352 ccgdm->gridData = gridData;
2353 ccgdm->gridFaces = gridFaces;
2354 ccgdm->gridAdjacency = gridAdjacency;
2355 ccgdm->gridOffset = gridOffset;
2358 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2360 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2362 ccgdm_create_grids(dm);
2363 return ccgdm->gridData;
2366 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2368 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2370 ccgdm_create_grids(dm);
2371 return ccgdm->gridAdjacency;
2374 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2376 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2378 ccgdm_create_grids(dm);
2379 return ccgdm->gridOffset;
2382 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2384 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2386 if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2389 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2390 me->totvert, me->totface);
2396 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2398 MultiresModifierData *mmd= ccgdm->multires.mmd;
2400 /* both of multires and subsurm modifiers are CCG, but
2401 grids should only be used when sculpting on multires */
2408 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2410 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2411 int gridSize, numGrids, grid_pbvh;
2421 grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2423 if(ob->sculpt->pbvh) {
2425 /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2426 but this can be freed on ccgdm release, this updates the pointers
2427 when the ccgdm gets remade, the assumption is that the topology
2429 ccgdm_create_grids(dm);
2430 BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2433 ccgdm->pbvh = ob->sculpt->pbvh;
2439 /* no pbvh exists yet, we need to create one. only in case of multires
2440 we build a pbvh over the modified mesh, in other cases the base mesh
2441 is being sculpted, so we build a pbvh from that. */
2443 ccgdm_create_grids(dm);
2445 gridSize = ccgDM_getGridSize(dm);
2446 numGrids = ccgDM_getNumGrids(dm);
2448 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2449 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2450 numGrids, gridSize, (void**)ccgdm->gridFaces);
2451 } else if(ob->type == OB_MESH) {
2453 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2454 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2455 me->totface, me->totvert);
2461 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2462 int drawInteriorEdges,
2466 CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2467 CCGVertIterator *vi;
2468 CCGEdgeIterator *ei;
2469 CCGFaceIterator *fi;
2470 int index, totvert, totedge, totface;
2472 int vertNum, edgeNum, faceNum;
2478 /*int gridSideVerts;*/
2480 int gridInternalEdges;
2481 MEdge *medge = NULL;
2482 MFace *mface = NULL;
2484 FaceVertWeight *qweight, *tweight;
2486 DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2487 ccgSubSurf_getNumFinalVerts(ss),
2488 ccgSubSurf_getNumFinalEdges(ss),
2489 ccgSubSurf_getNumFinalFaces(ss));
2491 ccgdm->dm.getMinMax = ccgDM_getMinMax;
2492 ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
2493 ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
2495 ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
2496 ccgdm->dm.getVert = ccgDM_getFinalVert;
2497 ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2498 ccgdm->dm.getFace = ccgDM_getFinalFace;
2499 ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2500 ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2501 ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2502 ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2503 ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
2504 ccgdm->dm.getVertData = DM_get_vert_data;
2505 ccgdm->dm.getEdgeData = DM_get_edge_data;
2506 ccgdm->dm.getFaceData = DM_get_face_data;
2507 ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2508 ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2509 ccgdm->dm.getFaceDataArray = ccgDM_get_face_data_layer;
2510 ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2511 ccgdm->dm.getGridSize = ccgDM_getGridSize;
2512 ccgdm->dm.getGridData = ccgDM_getGridData;
2513 ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2514 ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2515 ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2516 ccgdm->dm.getPBVH = ccgDM_getPBVH;
2518 ccgdm->dm.getVertCos = ccgdm_getVertCos;
2519 ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
2520 ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
2521 ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
2523 ccgdm->dm.drawVerts = ccgDM_drawVerts;
2524 ccgdm->dm.drawEdges = ccgDM_drawEdges;
2525 ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2526 ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2527 ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
2528 ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
2529 ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
2530 ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2531 ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
2532 ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
2533 ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat;
2534 ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
2536 ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
2537 ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
2539 ccgdm->dm.release = ccgDM_release;
2542 ccgdm->drawInteriorEdges = drawInteriorEdges;
2543 ccgdm->useSubsurfUv = useSubsurfUv;
2545 totvert = ccgSubSurf_getNumVerts(ss);
2546 ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2547 vi = ccgSubSurf_getVertIterator(ss);
2548 for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2549 CCGVert *v = ccgVertIterator_getCurrent(vi);
2551 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2553 ccgVertIterator_free(vi);
2555 totedge = ccgSubSurf_getNumEdges(ss);
2556 ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2557 ei = ccgSubSurf_getEdgeIterator(ss);
2558 for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2559 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2561 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2564 totface = ccgSubSurf_getNumFaces(ss);
2565 ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2566 fi = ccgSubSurf_getFaceIterator(ss);
2567 for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2568 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2570 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2572 ccgFaceIterator_free(fi);
2574 edgeSize = ccgSubSurf_getEdgeSize(ss);
2575 gridSize = ccgSubSurf_getGridSize(ss);
2576 gridFaces = gridSize - 1;
2577 /*gridSideVerts = gridSize - 2;*/ /*UNUSED*/
2578 /*gridInternalVerts = gridSideVerts * gridSideVerts; */ /*UNUSED*/
2579 gridSideEdges = gridSize - 1;
2580 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
2582 calc_ss_weights(gridFaces, &qweight, &tweight);
2588 /* mvert = dm->getVertArray(dm); - as yet unused */
2589 medge = dm->getEdgeArray(dm);
2590 mface = dm->getFaceArray(dm);
2592 faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
2594 orig_indices = (int*)ccgdm->dm.getFaceDataArray(&ccgdm->dm, CD_ORIGINDEX);
2595 for(index = 0; index < totface; ++index) {
2596 CCGFace *f = ccgdm->faceMap[index].face;
2597 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2598 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2599 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2600 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
2604 ccgdm->faceMap[index].startVert = vertNum;
2605 ccgdm->faceMap[index].startEdge = edgeNum;
2606 ccgdm->faceMap[index].startFace = faceNum;
2609 orig_indices[faceNum] = origIndex;
2611 /* set the face base vert */
2612 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2614 for(S = 0; S < numVerts; S++) {
2615 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
2617 vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2620 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
2624 for(S = 0; S < numVerts; S++) {
2625 int prevS = (S - 1 + numVerts) % numVerts;
2626 int nextS = (S + 1) % numVerts;
2627 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2628 for(x = 1; x < gridFaces; x++) {
2630 w[prevS] = weight[x][0][0];
2631 w[S] = weight[x][0][1];
2632 w[nextS] = weight[x][0][2];
2633 w[otherS] = weight[x][0][3];
2634 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2640 for(S = 0; S < numVerts; S++) {
2641 int prevS = (S - 1 + numVerts) % numVerts;
2642 int nextS = (S + 1) % numVerts;
2643 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2644 for(y = 1; y < gridFaces; y++) {
2645 for(x = 1; x < gridFaces; x++) {
2647 w[prevS] = weight[y * gridFaces + x][0][0];
2648 w[S] = weight[y * gridFaces + x][0][1];
2649 w[nextS] = weight[y * gridFaces + x][0][2];
2650 w[otherS] = weight[y * gridFaces + x][0][3];
2651 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2658 for(S = 0; S < numVerts; S++) {
2659 int prevS = (S - 1 + numVerts) % numVerts;
2660 int nextS = (S + 1) % numVerts;
2661 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2663 weight = (numVerts == 4) ? qweight : tweight;
2665 for(y = 0; y < gridFaces; y++) {
2666 for(x = 0; x < gridFaces; x++) {
2670 for(j = 0; j < 4; ++j) {
2671 w[j][prevS] = (*weight)[j][0];
2672 w[j][S] = (*weight)[j][1];
2673 w[j][nextS] = (*weight)[j][2];
2674 w[j][otherS] = (*weight)[j][3];
2677 DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
2686 faceFlags[index*2] = mface[origIndex].flag;
2687 faceFlags[index*2 + 1] = mface[origIndex].mat_nr;
2689 edgeNum += numFinalEdges;
2693 CustomData *fdata = &ccgdm->dm.faceData;
2694 CustomData *dmfdata = &dm->faceData;
2695 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
2696 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
2698 for (i=0; i<numlayer && i<dmnumlayer; i++)
2699 set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2702 edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "edgeFlags");
2704 for(index = 0; index < totedge; ++index) {
2705 CCGEdge *e = ccgdm->edgeMap[index].edge;
2706 int numFinalEdges = edgeSize - 1;
2709 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
2712 v = ccgSubSurf_getEdgeVert0(e);
2713 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2714 v = ccgSubSurf_getEdgeVert1(e);
2715 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2717 ccgdm->edgeMap[index].startVert = vertNum;
2718 ccgdm->edgeMap[index].startEdge = edgeNum;
2720 /* set the edge base vert */
2721 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2723 for(x = 1; x < edgeSize - 1; x++) {
2725 w[1] = (float) x / (edgeSize - 1);
2727 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2731 edgeFlags[index]= medge[edgeIdx].flag;
2733 edgeNum += numFinalEdges;
2736 for(index = 0; index < totvert; ++index) {
2737 CCGVert *v = ccgdm->vertMap[index].vert;
2740 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2742 ccgdm->vertMap[index].startVert = vertNum;
2744 /* set the vert base vert */
2745 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2747 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2760 struct DerivedMesh *subsurf_make_derived_from_derived(
2761 struct DerivedMesh *dm,
2762 struct SubsurfModifierData *smd,
2763 int useRenderParams, float (*vertCos)[3],
2764 int isFinalCalc, int forEditMode, int inEditMode)
2766 int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
2767 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2768 int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
2769 int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2770 CCGDerivedMesh *result;
2773 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2775 smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0,
2777 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
2779 result = getCCGDerivedMesh(smd->emCache,
2782 } else if(useRenderParams) {
2783 /* Do not use cache in render mode. */
2785 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->renderLevels): smd->renderLevels;
2790 ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2792 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2794 result = getCCGDerivedMesh(ss,
2795 drawInteriorEdges, useSubsurfUv, dm);
2799 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2800 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2801 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2804 /* It is quite possible there is a much better place to do this. It
2805 * depends a bit on how rigourously we expect this function to never
2806 * be called in editmode. In semi-theory we could share a single
2807 * cache, but the handles used inside and outside editmode are not
2808 * the same so we would need some way of converting them. Its probably
2809 * not worth the effort. But then why am I even writing this long
2810 * comment that no one will read? Hmmm. - zr
2812 * Addendum: we can't really ensure that this is never called in edit
2813 * mode, so now we have a parameter to verify it. - brecht
2815 if(!inEditMode && smd->emCache) {
2816 ccgSubSurf_free(smd->emCache);
2817 smd->emCache = NULL;
2820 if(useIncremental && isFinalCalc) {
2821 smd->mCache = ss = _getSubSurf(smd->mCache, levels,
2822 useAging, 0, useSimple);
2824 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2826 result = getCCGDerivedMesh(smd->mCache,
2830 if (smd->mCache && isFinalCalc) {
2831 ccgSubSurf_free(smd->mCache);