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_utildefines.h"
50 #include "BLI_blenlib.h"
51 #include "BLI_edgehash.h"
53 #include "BLI_memarena.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"
63 #include "BKE_tessmesh.h"
66 #include "BLI_array.h"
69 #include "BIF_glutil.h"
72 #include "GPU_extensions.h"
73 #include "GPU_material.h"
75 #include "CCGSubSurf.h"
77 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
78 int drawInteriorEdges,
81 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
85 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
86 return BLI_memarena_alloc(a, numBytes);
88 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
89 void *p2 = BLI_memarena_alloc(a, newSize);
91 memcpy(p2, ptr, oldSize);
95 static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr)) {
97 static void arena_release(CCGAllocatorHDL a) {
101 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int UNUSED(useFlatSubdiv)) {
105 /* subdivLevels==0 is not allowed */
106 subdivLevels = MAX2(subdivLevels, 1);
111 useAging = !!useAging;
112 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
114 if (oldUseAging!=useAging) {
115 ccgSubSurf_free(prevSS);
117 ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
124 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
126 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
128 ifc.vertDataSize = sizeof(DMGridData);
131 CCGAllocatorIFC allocatorIFC;
132 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16), "subsurf arena");
134 allocatorIFC.alloc = arena_alloc;
135 allocatorIFC.realloc = arena_realloc;
136 allocatorIFC.free = arena_free;
137 allocatorIFC.release = arena_release;
139 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
141 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
145 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
148 ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(DMGridData, no));
153 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
154 CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
155 CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
156 int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
157 int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
158 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
162 } else if (x==edgeSize-1) {
165 return edgeBase + x-1;
169 BM_INLINE int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
170 int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
171 int numVerts = ccgSubSurf_getFaceNumVerts(f);
173 if (x==gridSize-1 && y==gridSize-1) {
174 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
175 return *((int*) ccgSubSurf_getVertUserData(ss, v));
176 } else if (x==gridSize-1) {
177 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
178 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
179 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
180 if (v==ccgSubSurf_getEdgeVert0(e)) {
181 return edgeBase + (gridSize-1-y)-1;
183 return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
185 } else if (y==gridSize-1) {
186 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
187 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
188 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
189 if (v==ccgSubSurf_getEdgeVert0(e)) {
190 return edgeBase + (gridSize-1-x)-1;
192 return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
194 } else if (x==0 && y==0) {
197 S = (S+numVerts-1)%numVerts;
198 return faceBase + 1 + (gridSize-2)*S + (y-1);
200 return faceBase + 1 + (gridSize-2)*S + (x-1);
202 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
206 static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) {
207 unsigned int *fv = &mf->v1;
209 int j, nverts= mf->v4? 4: 3;
211 for (j=0; j<nverts; j++, fv++) {
212 for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) {
219 fverts[j]= SET_INT_IN_POINTER(nv->f*4 + nv->tfindex);
223 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MTFace *tface) {
230 MFace *mface = dm->getTessFaceArray(dm);
231 MVert *mvert = dm->getVertArray(dm);
232 int totvert = dm->getNumVerts(dm);
233 int totface = dm->getNumTessFaces(dm);
238 CCGVertHDL fverts[4];
240 float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
242 limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
243 vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit);
247 ccgSubSurf_initFullSync(ss);
249 /* create vertices */
250 for (i=0; i<totvert; i++) {
251 if (!get_uv_map_vert(vmap, i))
254 for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next)
258 seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED);
260 for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
263 CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
266 uv[0]= (tface+v->f)->uv[v->tfindex][0];
267 uv[1]= (tface+v->f)->uv[v->tfindex][1];
270 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
276 ehash = BLI_edgehash_new();
278 for (i=0; i<totface; i++) {
279 MFace *mf = &((MFace*) mface)[i];
280 int nverts= mf->v4? 4: 3;
281 CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i));
282 unsigned int *fv = &mf->v1;
284 get_face_uv_map_vert(vmap, mf, i, fverts);
286 for (j=0; j<nverts; j++) {
287 int v0 = GET_INT_FROM_POINTER(fverts[j]);
288 int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]);
289 MVert *mv0 = mvert + *(fv+j);
290 MVert *mv1 = mvert + *(fv+((j+1)%nverts));
292 if (!BLI_edgehash_haskey(ehash, v0, v1)) {
293 CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j);
294 CCGEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j);
297 if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
298 crease = creaseFactor;
300 crease = ccgSubSurf_getEdgeCrease(orige);
302 ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e);
303 BLI_edgehash_insert(ehash, v0, v1, NULL);
308 BLI_edgehash_free(ehash, NULL);
311 for (i=0; i<totface; i++) {
312 MFace *mf = &((MFace*) mface)[i];
313 int nverts= mf->v4? 4: 3;
316 get_face_uv_map_vert(vmap, mf, i, fverts);
317 ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f);
320 free_uv_vert_map(vmap);
321 ccgSubSurf_processSync(ss);
327 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
333 int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
334 MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n);
335 MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
337 if(!dmtface || !tface)
340 /* create a CCGSubSurf from uv's */
341 uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0);
343 if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) {
344 ccgSubSurf_free(uvss);
348 /* get some info from CCGSubSurf */
349 totface = ccgSubSurf_getNumFaces(uvss);
350 /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
351 gridSize = ccgSubSurf_getGridSize(uvss);
352 gridFaces = gridSize - 1;
354 /* make a map from original faces to CCGFaces */
355 faceMap = MEM_mallocN(totface*sizeof(*faceMap), "facemapuv");
357 fi = ccgSubSurf_getFaceIterator(uvss);
358 for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
359 CCGFace *f = ccgFaceIterator_getCurrent(fi);
360 faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(uvss, f))] = f;
362 ccgFaceIterator_free(fi);
364 /* load coordinates from uvss into tface */
367 for(index = 0; index < totface; index++) {
368 CCGFace *f = faceMap[index];
369 int numVerts = ccgSubSurf_getFaceNumVerts(f);
371 for (S=0; S<numVerts; S++) {
372 DMGridData *faceGridData= ccgSubSurf_getFaceGridDataArray(uvss, f, S);
374 for(y = 0; y < gridFaces; y++) {
375 for(x = 0; x < gridFaces; x++) {
376 float *a = faceGridData[(y + 0)*gridSize + x + 0].co;
377 float *b = faceGridData[(y + 0)*gridSize + x + 1].co;
378 float *c = faceGridData[(y + 1)*gridSize + x + 1].co;
379 float *d = faceGridData[(y + 1)*gridSize + x + 0].co;
381 tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1];
382 tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1];
383 tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1];
384 tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1];
392 ccgSubSurf_free(uvss);
397 typedef struct FaceVertWeightEntry {
398 FaceVertWeight *weight;
401 } FaceVertWeightEntry;
403 typedef struct WeightTable {
404 FaceVertWeightEntry *weight_table;
408 static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
411 float *w, w1, w2, w4, fac, fac2, fx, fy;
413 if (wtable->len <= faceLen) {
414 void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry)*(faceLen+1), "weight table alloc 2");
417 memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry)*wtable->len);
418 MEM_freeN(wtable->weight_table);
421 wtable->weight_table = tmp;
422 wtable->len = faceLen+1;
425 if (!wtable->weight_table[faceLen].valid) {
426 wtable->weight_table[faceLen].valid = 1;
427 wtable->weight_table[faceLen].w = w = MEM_callocN(sizeof(float)*faceLen*faceLen*(gridCuts+2)*(gridCuts+2), "weight table alloc");
428 fac = 1.0f / (float)faceLen;
430 for (i=0; i<faceLen; i++) {
431 for (x=0; x<gridCuts+2; x++) {
432 for (y=0; y<gridCuts+2; y++) {
433 fx = 0.5f - (float)x / (float)(gridCuts+1) / 2.0f;
434 fy = 0.5f - (float)y / (float)(gridCuts+1) / 2.0f;
437 w1 = (1.0f - fx) * (1.0f - fy) + (-fac2*fx*fy*fac);
438 w2 = (1.0f - fx + fac2*fx*-fac) * (fy);
439 w4 = (fx) * (1.0f - fy + -fac2*fy*fac);
441 fac2 = 1.0f - (w1+w2+w4);
442 fac2 = fac2 / (float)(faceLen-3);
443 for (j=0; j<faceLen; j++)
447 w[(i-1+faceLen)%faceLen] = w2;
448 w[(i+1)%faceLen] = w4;
456 return wtable->weight_table[faceLen].w;
459 static void free_ss_weights(WeightTable *wtable)
463 for (i=0; i<wtable->len; i++) {
464 if (wtable->weight_table[i].valid)
465 MEM_freeN(wtable->weight_table[i].w);
468 if (wtable->weight_table)
469 MEM_freeN(wtable->weight_table);
473 static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
474 int drawInteriorEdges, int useSubsurfUv,
475 DerivedMesh *dm, struct MultiresSubsurf *ms)
477 DerivedMesh *cgdm, *result;
478 double curt = PIL_check_seconds_timer();
480 cgdm = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
481 result = CDDM_copy(cgdm, 1);
483 printf("subsurf conversion time: %.6lf\n", PIL_check_seconds_timer() - curt);
488 CDDM_calc_normals(result);
494 static int ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
495 float (*vertexCos)[3], int useFlatSubdiv)
497 float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
498 CCGVertHDL *fVerts = NULL;
499 BLI_array_declare(fVerts);
500 MVert *mvert = dm->getVertArray(dm);
501 MEdge *medge = dm->getEdgeArray(dm);
502 /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
505 MLoop *mloop = dm->getLoopArray(dm), *ml;
506 MPoly *mpoly = dm->getPolyArray(dm), *mp;
507 /*MFace *mf;*/ /*UNUSED*/
508 int totvert = dm->getNumVerts(dm);
509 int totedge = dm->getNumEdges(dm);
510 /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
511 /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/
515 ccgSubSurf_initFullSync(ss);
518 index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
519 for(i = 0; i < totvert; i++, mv++) {
523 ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v);
525 ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v);
528 ((int*)ccgSubSurf_getVertUserData(ss, v))[1] = (index)? *index++: i;
532 index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
533 for(i = 0; i < totedge; i++, me++) {
537 crease = useFlatSubdiv ? creaseFactor :
538 me->crease * creaseFactor / 255.0f;
540 ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1),
541 SET_INT_IN_POINTER(me->v2), crease, &e);
543 ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index)? *index++: i;
547 index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
548 for (i=0; i<dm->numPolyData; i++, mp++) {
551 BLI_array_empty(fVerts);
553 ml = mloop + mp->loopstart;
554 for (j=0; j<mp->totloop; j++, ml++) {
555 BLI_array_append(fVerts, SET_INT_IN_POINTER(ml->v));
558 /* this is very bad, means mesh is internally inconsistent.
559 * it is not really possible to continue without modifying
560 * other parts of code significantly to handle missing faces.
561 * since this really shouldn't even be possible we just bail.*/
562 if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), mp->totloop,
563 fVerts, &f) == eCCGError_InvalidValue) {
564 static int hasGivenError = 0;
567 printf("Unrecoverable error in SubSurf calculation,"
568 " mesh is inconsistent.\n");
576 ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = index ? *index++: i;
579 ccgSubSurf_processSync(ss);
581 BLI_array_free(fVerts);
587 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v) {
588 return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
591 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e) {
592 return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
595 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) {
596 return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
599 static void cgdm_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
600 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
601 CCGSubSurf *ss = cgdm->ss;
602 CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
603 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
604 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
605 int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
606 int gridSize = ccgSubSurf_getGridSize(ss);
608 if (!ccgSubSurf_getNumVerts(ss))
609 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
611 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
612 CCGVert *v = ccgVertIterator_getCurrent(vi);
613 float *co = ccgSubSurf_getVertData(ss, v);
615 DO_MINMAX(co, min_r, max_r);
618 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
619 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
620 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
622 for (i=0; i<edgeSize; i++)
623 DO_MINMAX(edgeData[i].co, min_r, max_r);
626 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
627 CCGFace *f = ccgFaceIterator_getCurrent(fi);
628 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
630 for (S=0; S<numVerts; S++) {
631 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
633 for (y=0; y<gridSize; y++)
634 for (x=0; x<gridSize; x++)
635 DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
639 ccgFaceIterator_free(fi);
640 ccgEdgeIterator_free(ei);
641 ccgVertIterator_free(vi);
643 static int cgdm_getNumVerts(DerivedMesh *dm) {
644 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
646 return ccgSubSurf_getNumFinalVerts(cgdm->ss);
648 static int cgdm_getNumEdges(DerivedMesh *dm) {
649 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
651 return ccgSubSurf_getNumFinalEdges(cgdm->ss);
653 static int cgdm_getNumTessFaces(DerivedMesh *dm) {
654 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
656 return ccgSubSurf_getNumFinalFaces(cgdm->ss);
659 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
661 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
662 CCGSubSurf *ss = cgdm->ss;
666 memset(mv, 0, sizeof(*mv));
668 if((vertNum < cgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
669 /* this vert comes from face data */
670 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
672 int x, y, grid, numVerts;
674 int gridSize = ccgSubSurf_getGridSize(ss);
676 int gridInternalVerts;
681 while(i < lastface && vertNum >= cgdm->faceMap[i + 1].startVert)
684 f = cgdm->faceMap[i].face;
685 numVerts = ccgSubSurf_getFaceNumVerts(f);
687 gridSideVerts = gridSize - 2;
688 gridInternalVerts = gridSideVerts * gridSideVerts;
690 gridSideEnd = 1 + numVerts * gridSideVerts;
691 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
693 offset = vertNum - cgdm->faceMap[i].startVert;
695 vd = ccgSubSurf_getFaceCenterData(f);
696 copy_v3_v3(mv->co, vd->co);
697 normal_float_to_short_v3(mv->no, vd->no);
698 } else if(offset < gridSideEnd) {
700 grid = offset / gridSideVerts;
701 x = offset % gridSideVerts + 1;
702 vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
703 copy_v3_v3(mv->co, vd->co);
704 normal_float_to_short_v3(mv->no, vd->no);
705 } else if(offset < gridInternalEnd) {
706 offset -= gridSideEnd;
707 grid = offset / gridInternalVerts;
708 offset %= gridInternalVerts;
709 y = offset / gridSideVerts + 1;
710 x = offset % gridSideVerts + 1;
711 vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
712 copy_v3_v3(mv->co, vd->co);
713 normal_float_to_short_v3(mv->no, vd->no);
715 } else if((vertNum < cgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
716 /* this vert comes from edge data */
718 int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
722 while(i < lastedge && vertNum >= cgdm->edgeMap[i + 1].startVert)
725 e = cgdm->edgeMap[i].edge;
727 x = vertNum - cgdm->edgeMap[i].startVert + 1;
728 vd = ccgSubSurf_getEdgeData(ss, e, x);
729 copy_v3_v3(mv->co, vd->co);
730 normal_float_to_short_v3(mv->no, vd->no);
732 /* this vert comes from vert data */
734 i = vertNum - cgdm->vertMap[0].startVert;
736 v = cgdm->vertMap[i].vert;
737 vd = ccgSubSurf_getVertData(ss, v);
738 copy_v3_v3(mv->co, vd->co);
739 normal_float_to_short_v3(mv->no, vd->no);
743 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float co_r[3])
747 ccgDM_getFinalVert(dm, vertNum, &mvert);
748 VECCOPY(co_r, mvert.co);
751 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3])
755 ccgDM_getFinalVert(dm, vertNum, &mvert);
756 normal_short_to_float_v3(no_r, mvert.no);
759 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
761 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
762 CCGSubSurf *ss = cgdm->ss;
765 memset(med, 0, sizeof(*med));
767 if(edgeNum < cgdm->edgeMap[0].startEdge) {
768 /* this edge comes from face data */
769 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
771 int x, y, grid /*, numVerts*/;
773 int gridSize = ccgSubSurf_getGridSize(ss);
774 int edgeSize = ccgSubSurf_getEdgeSize(ss);
776 int gridInternalEdges;
783 if (cgdm->faceMap[i].startEdge >= edgeNum) {
784 i -= fabsf(i-lasti)/2.0f;
785 } else if (cgdm->faceMap[i].startEdge < edgeNum) {
786 i += fabsf(i-lasti)/2.0f;
808 i = i > 0 ? i - 1 : i;
809 while(i < lastface && edgeNum >= cgdm->faceMap[i + 1].startEdge)
812 f = cgdm->faceMap[i].face;
813 /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
815 gridSideEdges = gridSize - 1;
816 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
818 offset = edgeNum - cgdm->faceMap[i].startEdge;
819 grid = offset / (gridSideEdges + gridInternalEdges);
820 offset %= (gridSideEdges + gridInternalEdges);
822 if(offset < gridSideEdges) {
824 med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
825 med->v2 = getFaceIndex(ss, f, grid, x+1, 0, edgeSize, gridSize);
827 offset -= gridSideEdges;
828 x = (offset / 2) / gridSideEdges + 1;
829 y = (offset / 2) % gridSideEdges;
830 if(offset % 2 == 0) {
831 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
832 med->v2 = getFaceIndex(ss, f, grid, x, y+1, edgeSize, gridSize);
834 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
835 med->v2 = getFaceIndex(ss, f, grid, y+1, x, edgeSize, gridSize);
839 /* this vert comes from edge data */
841 int edgeSize = ccgSubSurf_getEdgeSize(ss);
844 unsigned int flags = 0;
846 i = (edgeNum - cgdm->edgeMap[0].startEdge) / (edgeSize - 1);
848 e = cgdm->edgeMap[i].edge;
850 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
852 x = edgeNum - cgdm->edgeMap[i].startEdge;
854 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
855 med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
857 edgeFlag = (cgdm->edgeFlags)? &cgdm->edgeFlags[i]: NULL;
859 flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
860 | ME_EDGEDRAW | ME_EDGERENDER;
862 flags |= ME_EDGEDRAW | ME_EDGERENDER;
868 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
870 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
871 CCGSubSurf *ss = cgdm->ss;
872 int gridSize = ccgSubSurf_getGridSize(ss);
873 int edgeSize = ccgSubSurf_getEdgeSize(ss);
874 int gridSideEdges = gridSize - 1;
875 int gridFaces = gridSideEdges * gridSideEdges;
882 /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
883 char *faceFlags = cgdm->faceFlags;
885 memset(mf, 0, sizeof(*mf));
886 if (faceNum >= cgdm->dm.numFaceData)
889 i = cgdm->reverseFaceMap[faceNum];
891 f = cgdm->faceMap[i].face;
892 /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
894 offset = faceNum - cgdm->faceMap[i].startFace;
895 grid = offset / gridFaces;
897 y = offset / gridSideEdges;
898 x = offset % gridSideEdges;
900 mf->v1 = getFaceIndex(ss, f, grid, x+0, y+0, edgeSize, gridSize);
901 mf->v2 = getFaceIndex(ss, f, grid, x+0, y+1, edgeSize, gridSize);
902 mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize);
903 mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize);
906 mf->flag = faceFlags[i*2];
907 mf->mat_nr = faceFlags[i*2+1];
909 else mf->flag = ME_SMOOTH;
912 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
914 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
915 CCGSubSurf *ss = cgdm->ss;
918 int totvert, totedge, totface;
919 int gridSize = ccgSubSurf_getGridSize(ss);
920 int edgeSize = ccgSubSurf_getEdgeSize(ss);
923 totface = ccgSubSurf_getNumFaces(ss);
924 for(index = 0; index < totface; index++) {
925 CCGFace *f = cgdm->faceMap[index].face;
926 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
928 vd= ccgSubSurf_getFaceCenterData(f);
929 copy_v3_v3(mvert[i].co, vd->co);
930 normal_float_to_short_v3(mvert[i].no, vd->no);
933 for(S = 0; S < numVerts; S++) {
934 for(x = 1; x < gridSize - 1; x++, i++) {
935 vd= ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
936 copy_v3_v3(mvert[i].co, vd->co);
937 normal_float_to_short_v3(mvert[i].no, vd->no);
941 for(S = 0; S < numVerts; S++) {
942 for(y = 1; y < gridSize - 1; y++) {
943 for(x = 1; x < gridSize - 1; x++, i++) {
944 vd= ccgSubSurf_getFaceGridData(ss, f, S, x, y);
945 copy_v3_v3(mvert[i].co, vd->co);
946 normal_float_to_short_v3(mvert[i].no, vd->no);
952 totedge = ccgSubSurf_getNumEdges(ss);
953 for(index = 0; index < totedge; index++) {
954 CCGEdge *e = cgdm->edgeMap[index].edge;
957 for(x = 1; x < edgeSize - 1; x++, i++) {
958 vd= ccgSubSurf_getEdgeData(ss, e, x);
959 copy_v3_v3(mvert[i].co, vd->co);
960 /* This gives errors with -debug-fpe
961 * the normals dont seem to be unit length.
962 * this is most likely caused by edges with no
963 * faces which are now zerod out, see comment in:
964 * ccgSubSurf__calcVertNormals(), - campbell */
965 normal_float_to_short_v3(mvert[i].no, vd->no);
969 totvert = ccgSubSurf_getNumVerts(ss);
970 for(index = 0; index < totvert; index++) {
971 CCGVert *v = cgdm->vertMap[index].vert;
973 vd= ccgSubSurf_getVertData(ss, v);
974 copy_v3_v3(mvert[i].co, vd->co);
975 normal_float_to_short_v3(mvert[i].no, vd->no);
980 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
982 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
983 CCGSubSurf *ss = cgdm->ss;
985 int totedge, totface;
986 int gridSize = ccgSubSurf_getGridSize(ss);
987 int edgeSize = ccgSubSurf_getEdgeSize(ss);
989 short *edgeFlags = cgdm->edgeFlags;
991 totface = ccgSubSurf_getNumFaces(ss);
992 for(index = 0; index < totface; index++) {
993 CCGFace *f = cgdm->faceMap[index].face;
994 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
996 for(S = 0; S < numVerts; S++) {
997 for(x = 0; x < gridSize - 1; x++) {
998 MEdge *med = &medge[i];
1000 if(cgdm->drawInteriorEdges)
1001 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1002 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
1003 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
1007 for(x = 1; x < gridSize - 1; x++) {
1008 for(y = 0; y < gridSize - 1; y++) {
1012 if(cgdm->drawInteriorEdges)
1013 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1014 med->v1 = getFaceIndex(ss, f, S, x, y,
1015 edgeSize, gridSize);
1016 med->v2 = getFaceIndex(ss, f, S, x, y + 1,
1017 edgeSize, gridSize);
1021 if(cgdm->drawInteriorEdges)
1022 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1023 med->v1 = getFaceIndex(ss, f, S, y, x,
1024 edgeSize, gridSize);
1025 med->v2 = getFaceIndex(ss, f, S, y + 1, x,
1026 edgeSize, gridSize);
1033 totedge = ccgSubSurf_getNumEdges(ss);
1034 for(index = 0; index < totedge; index++) {
1035 CCGEdge *e = cgdm->edgeMap[index].edge;
1036 unsigned int flags = 0;
1038 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
1040 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
1044 flags |= (edgeFlags[index] & (ME_SEAM | ME_SHARP))
1045 | ME_EDGEDRAW | ME_EDGERENDER;
1048 flags |= ME_EDGEDRAW | ME_EDGERENDER;
1051 for(x = 0; x < edgeSize - 1; x++) {
1052 MEdge *med = &medge[i];
1053 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1054 med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
1061 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1063 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1064 CCGSubSurf *ss = cgdm->ss;
1067 int gridSize = ccgSubSurf_getGridSize(ss);
1068 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1070 char *faceFlags = cgdm->faceFlags;
1072 totface = ccgSubSurf_getNumFaces(ss);
1073 for(index = 0; index < totface; index++) {
1074 CCGFace *f = cgdm->faceMap[index].face;
1075 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1076 int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
1077 int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
1079 for(S = 0; S < numVerts; S++) {
1080 for(y = 0; y < gridSize - 1; y++) {
1081 for(x = 0; x < gridSize - 1; x++) {
1082 MFace *mf = &mface[i];
1083 mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1084 edgeSize, gridSize);
1085 mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1086 edgeSize, gridSize);
1087 mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1088 edgeSize, gridSize);
1089 mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1090 edgeSize, gridSize);
1092 mat_nr = faceFlags[index*2+1];
1093 mf->flag = faceFlags[index*2];
1094 } else mf->flag = flag;
1096 mf->mat_nr = mat_nr;
1106 static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
1108 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1109 CCGSubSurf *ss = cgdm->ss;
1112 int gridSize = ccgSubSurf_getGridSize(ss);
1113 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1116 /* char *faceFlags = cgdm->faceFlags; */ /* UNUSED */
1121 cgdm->ehash = BLI_edgehash_new();
1122 medge = cgdm->dm.getEdgeArray((DerivedMesh*)cgdm);
1124 for (i=0; i<cgdm->dm.numEdgeData; i++) {
1125 BLI_edgehash_insert(cgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
1129 totface = ccgSubSurf_getNumFaces(ss);
1131 for(index = 0; index < totface; index++) {
1132 CCGFace *f = cgdm->faceMap[index].face;
1133 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1134 /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */
1135 /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */
1137 for(S = 0; S < numVerts; S++) {
1138 for(y = 0; y < gridSize - 1; y++) {
1139 for(x = 0; x < gridSize - 1; x++) {
1142 v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1143 edgeSize, gridSize);
1145 v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1146 edgeSize, gridSize);
1147 v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1148 edgeSize, gridSize);
1149 v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1150 edgeSize, gridSize);
1153 mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v1, v2));
1157 mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v2, v3));
1161 mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v3, v4));
1165 mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v4, v1));
1174 static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mface)
1176 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1177 CCGSubSurf *ss = cgdm->ss;
1180 int gridSize = ccgSubSurf_getGridSize(ss);
1181 /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
1183 char *faceFlags = cgdm->faceFlags;
1185 totface = ccgSubSurf_getNumFaces(ss);
1186 for(index = 0; index < totface; index++) {
1187 CCGFace *f = cgdm->faceMap[index].face;
1188 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1189 int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
1190 int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
1192 for(S = 0; S < numVerts; S++) {
1193 for(y = 0; y < gridSize - 1; y++) {
1194 for(x = 0; x < gridSize - 1; x++) {
1195 MPoly *mf = &mface[i];
1198 mat_nr = faceFlags[index*2+1];
1199 mf->flag = faceFlags[index*2];
1200 } else mf->flag = flag;
1202 mf->mat_nr = mat_nr;
1215 static void cgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
1216 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1217 CCGSubSurf *ss = cgdm->ss;
1218 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1219 int gridSize = ccgSubSurf_getGridSize(ss);
1221 CCGVertIterator *vi;
1222 CCGEdgeIterator *ei;
1223 CCGFaceIterator *fi;
1227 int index, totvert, totedge, totface;
1229 totvert = ccgSubSurf_getNumVerts(ss);
1230 vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1231 vi = ccgSubSurf_getVertIterator(ss);
1232 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1233 CCGVert *v = ccgVertIterator_getCurrent(vi);
1235 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1237 ccgVertIterator_free(vi);
1239 totedge = ccgSubSurf_getNumEdges(ss);
1240 edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1241 ei = ccgSubSurf_getEdgeIterator(ss);
1242 for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1243 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1245 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1248 totface = ccgSubSurf_getNumFaces(ss);
1249 faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1250 fi = ccgSubSurf_getFaceIterator(ss);
1251 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1252 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1254 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
1256 ccgFaceIterator_free(fi);
1259 for (index=0; index<totface; index++) {
1260 CCGFace *f = faceMap2[index];
1261 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1263 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
1265 for (S=0; S<numVerts; S++) {
1266 for (x=1; x<gridSize-1; x++) {
1267 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1271 for (S=0; S<numVerts; S++) {
1272 for (y=1; y<gridSize-1; y++) {
1273 for (x=1; x<gridSize-1; x++) {
1274 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1280 for (index=0; index<totedge; index++) {
1281 CCGEdge *e= edgeMap2[index];
1284 for (x=1; x<edgeSize-1; x++) {
1285 copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1289 for (index=0; index<totvert; index++) {
1290 CCGVert *v = vertMap2[index];
1291 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
1294 MEM_freeN(vertMap2);
1295 MEM_freeN(edgeMap2);
1296 MEM_freeN(faceMap2);
1298 static void cgdm_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1299 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1300 CCGVertIterator *vi = ccgSubSurf_getVertIterator(cgdm->ss);
1302 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1303 CCGVert *v = ccgVertIterator_getCurrent(vi);
1304 DMGridData *vd = ccgSubSurf_getVertData(cgdm->ss, v);
1305 int index = ccgDM_getVertMapIndex(cgdm->ss, v);
1308 func(userData, index, vd->co, vd->no, NULL);
1311 ccgVertIterator_free(vi);
1313 static void cgdm_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1314 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1315 CCGSubSurf *ss = cgdm->ss;
1316 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1317 int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1319 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1320 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1321 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1322 int index = ccgDM_getEdgeMapIndex(ss, e);
1325 for (i=0; i<edgeSize-1; i++)
1326 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1330 ccgEdgeIterator_free(ei);
1333 static void ccgDM_drawVerts(DerivedMesh *dm) {
1334 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1335 CCGSubSurf *ss = cgdm->ss;
1336 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1337 int gridSize = ccgSubSurf_getGridSize(ss);
1338 CCGVertIterator *vi;
1339 CCGEdgeIterator *ei;
1340 CCGFaceIterator *fi;
1343 vi = ccgSubSurf_getVertIterator(ss);
1344 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1345 CCGVert *v = ccgVertIterator_getCurrent(vi);
1346 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1348 ccgVertIterator_free(vi);
1350 ei = ccgSubSurf_getEdgeIterator(ss);
1351 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1352 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1355 for (x=1; x<edgeSize-1; x++)
1356 glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1358 ccgEdgeIterator_free(ei);
1360 fi = ccgSubSurf_getFaceIterator(ss);
1361 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1362 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1363 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1365 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1366 for (S=0; S<numVerts; S++)
1367 for (x=1; x<gridSize-1; x++)
1368 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1369 for (S=0; S<numVerts; S++)
1370 for (y=1; y<gridSize-1; y++)
1371 for (x=1; x<gridSize-1; x++)
1372 glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1374 ccgFaceIterator_free(fi);
1378 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
1380 if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
1384 BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void***)&faces, &totface);
1386 ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
1387 ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
1393 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(drawAllEdges)) {
1394 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1395 CCGSubSurf *ss = ccgdm->ss;
1396 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1397 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1398 int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1399 int totedge = ccgSubSurf_getNumEdges(ss);
1400 int gridSize = ccgSubSurf_getGridSize(ss);
1403 ccgdm_pbvh_update(ccgdm);
1405 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1407 for (j=0; j< totedge; j++) {
1408 CCGEdge *e = ccgdm->edgeMap[j].edge;
1409 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1411 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1414 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1417 if (useAging && !(G.f&G_BACKBUFSEL)) {
1418 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1419 glColor3ub(0, ageCol>0?ageCol:0, 0);
1422 glBegin(GL_LINE_STRIP);
1423 for (i=0; i<edgeSize-1; i++) {
1424 glVertex3fv(edgeData[i].co);
1425 glVertex3fv(edgeData[i+1].co);
1430 if (useAging && !(G.f&G_BACKBUFSEL)) {
1431 glColor3ub(0, 0, 0);
1434 if (ccgdm->drawInteriorEdges) {
1435 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1436 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1437 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1439 for (S=0; S<numVerts; S++) {
1440 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1442 glBegin(GL_LINE_STRIP);
1443 for (x=0; x<gridSize; x++)
1444 glVertex3fv(faceGridData[x].co);
1446 for (y=1; y<gridSize-1; y++) {
1447 glBegin(GL_LINE_STRIP);
1448 for (x=0; x<gridSize; x++)
1449 glVertex3fv(faceGridData[y*gridSize + x].co);
1452 for (x=1; x<gridSize-1; x++) {
1453 glBegin(GL_LINE_STRIP);
1454 for (y=0; y<gridSize; y++)
1455 glVertex3fv(faceGridData[y*gridSize + x].co);
1462 ccgFaceIterator_free(fi);
1463 ccgEdgeIterator_free(ei);
1465 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1466 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1467 CCGSubSurf *ss = cgdm->ss;
1468 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1469 int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1471 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1472 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1473 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1475 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1476 glBegin(GL_LINE_STRIP);
1477 for (i=0; i<edgeSize-1; i++) {
1478 glVertex3fv(edgeData[i].co);
1479 glVertex3fv(edgeData[i+1].co);
1485 ccgEdgeIterator_free(ei);
1488 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1490 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1491 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1494 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1495 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1496 no[2] = b_dX*a_cY - b_dY*a_cX;
1498 /* don't normalize, GL_NORMALIZE is enabled */
1502 /* Only used by non-editmesh types */
1503 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
1504 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1505 CCGSubSurf *ss = ccgdm->ss;
1506 CCGFaceIterator *fi;
1507 int gridSize = ccgSubSurf_getGridSize(ss);
1508 char *faceFlags = ccgdm->faceFlags;
1509 int step = (fast)? gridSize-1: 1;
1511 ccgdm_pbvh_update(ccgdm);
1513 if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1514 if(dm->numFaceData) {
1515 /* should be per face */
1516 if(!setMaterial(faceFlags[1]+1, NULL))
1519 glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
1520 BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH));
1521 glShadeModel(GL_FLAT);
1527 fi = ccgSubSurf_getFaceIterator(ss);
1528 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1529 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1530 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1531 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1532 int drawSmooth, mat_nr;
1535 drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1536 mat_nr= faceFlags[index*2 + 1];
1543 if (!setMaterial(mat_nr+1, NULL))
1546 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1547 for (S=0; S<numVerts; S++) {
1548 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1551 for (y=0; y<gridSize-1; y+=step) {
1552 glBegin(GL_QUAD_STRIP);
1553 for (x=0; x<gridSize; x+=step) {
1554 DMGridData *a = &faceGridData[(y+0)*gridSize + x];
1555 DMGridData *b = &faceGridData[(y+step)*gridSize + x];
1566 for (y=0; y<gridSize-1; y+=step) {
1567 for (x=0; x<gridSize-1; x+=step) {
1568 float *a = faceGridData[(y+0)*gridSize + x].co;
1569 float *b = faceGridData[(y+0)*gridSize + x + step].co;
1570 float *c = faceGridData[(y+step)*gridSize + x + step].co;
1571 float *d = faceGridData[(y+step)*gridSize + x].co;
1573 ccgDM_glNormalFast(a, b, c, d);
1586 ccgFaceIterator_free(fi);
1589 /* Only used by non-editmesh types */
1590 static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
1591 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1592 CCGSubSurf *ss = cgdm->ss;
1593 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1594 GPUVertexAttribs gattribs;
1595 DMVertexAttribs attribs= {{{NULL}}};
1596 MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE);
1597 int gridSize = ccgSubSurf_getGridSize(ss);
1598 int gridFaces = gridSize - 1;
1599 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1600 int transp, orig_transp, new_transp;
1601 char *faceFlags = cgdm->faceFlags;
1602 int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
1604 ccgdm_pbvh_update(cgdm);
1608 transp = GPU_get_material_blend_mode();
1609 orig_transp = transp;
1611 #define PASSATTRIB(dx, dy, vert) { \
1612 if(attribs.totorco) { \
1613 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize); \
1614 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \
1616 for(b = 0; b < attribs.tottface; b++) { \
1617 MTFace *tf = &attribs.tface[b].array[a]; \
1618 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \
1620 for(b = 0; b < attribs.totmcol; b++) { \
1621 MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \
1623 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
1624 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
1626 if(attribs.tottang) { \
1627 float *tang = attribs.tang.array[a*4 + vert]; \
1628 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \
1632 totface = ccgSubSurf_getNumFaces(ss);
1633 for(a = 0, i = 0; i < totface; i++) {
1634 CCGFace *f = cgdm->faceMap[i].face;
1635 int S, x, y, drawSmooth;
1636 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1637 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1639 numVerts = ccgSubSurf_getFaceNumVerts(f);
1642 drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1643 new_matnr= faceFlags[index*2 + 1] + 1;
1650 if(new_matnr != matnr) {
1651 doDraw = setMaterial(matnr = new_matnr, &gattribs);
1653 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1656 if(!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && !setDrawOptions(userData, origIndex))) {
1657 a += gridFaces*gridFaces*numVerts;
1662 new_transp = tf[i].transp;
1664 if(new_transp != transp) {
1665 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1666 GPU_set_material_blend_mode(orig_transp);
1668 GPU_set_material_blend_mode(new_transp);
1669 transp = new_transp;
1673 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1674 for (S=0; S<numVerts; S++) {
1675 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1676 DMGridData *vda, *vdb;
1679 for (y=0; y<gridFaces; y++) {
1680 glBegin(GL_QUAD_STRIP);
1681 for (x=0; x<gridFaces; x++) {
1682 vda = &faceGridData[(y+0)*gridSize + x];
1683 vdb = &faceGridData[(y+1)*gridSize + x];
1685 PASSATTRIB(0, 0, 0);
1686 glNormal3fv(vda->no);
1687 glVertex3fv(vda->co);
1689 PASSATTRIB(0, 1, 1);
1690 glNormal3fv(vdb->no);
1691 glVertex3fv(vdb->co);
1693 if(x != gridFaces-1)
1697 vda = &faceGridData[(y+0)*gridSize + x];
1698 vdb = &faceGridData[(y+1)*gridSize + x];
1700 PASSATTRIB(0, 0, 3);
1701 glNormal3fv(vda->no);
1702 glVertex3fv(vda->co);
1704 PASSATTRIB(0, 1, 2);
1705 glNormal3fv(vdb->no);
1706 glVertex3fv(vdb->co);
1714 for (y=0; y<gridFaces; y++) {
1715 for (x=0; x<gridFaces; x++) {
1716 float *aco = faceGridData[(y+0)*gridSize + x].co;
1717 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1718 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1719 float *dco = faceGridData[(y+1)*gridSize + x].co;
1721 ccgDM_glNormalFast(aco, bco, cco, dco);
1723 PASSATTRIB(0, 1, 1);
1725 PASSATTRIB(1, 1, 2);
1727 PASSATTRIB(1, 0, 3);
1729 PASSATTRIB(0, 0, 0);
1742 ccgFaceIterator_free(fi);
1745 static void cgdm_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1746 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1749 static void cgdm_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
1750 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1751 CCGSubSurf *ss = cgdm->ss;
1752 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1753 int gridSize = ccgSubSurf_getGridSize(ss);
1754 unsigned char *cp1, *cp2;
1757 ccgdm_pbvh_update(cgdm);
1767 glShadeModel(GL_SMOOTH);
1770 glEnable(GL_CULL_FACE);
1774 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1775 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1776 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1778 for (S=0; S<numVerts; S++) {
1779 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1780 for (y=0; y<gridSize-1; y++) {
1781 for (x=0; x<gridSize-1; x++) {
1782 float *a = faceGridData[(y+0)*gridSize + x].co;
1783 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1784 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1785 float *d = faceGridData[(y+1)*gridSize + x].co;
1787 glColor3ub(cp1[3], cp1[2], cp1[1]);
1789 glColor3ub(cp1[7], cp1[6], cp1[5]);
1791 glColor3ub(cp1[11], cp1[10], cp1[9]);
1793 glColor3ub(cp1[15], cp1[14], cp1[13]);
1797 glColor3ub(cp2[15], cp2[14], cp2[13]);
1799 glColor3ub(cp2[11], cp2[10], cp2[9]);
1801 glColor3ub(cp2[7], cp2[6], cp2[5]);
1803 glColor3ub(cp2[3], cp2[2], cp2[1]);
1815 ccgFaceIterator_free(fi);
1818 static void cgdm_drawFacesTex_common(DerivedMesh *dm,
1819 int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
1820 int (*drawParamsMapped)(void *userData, int index),
1823 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1824 CCGSubSurf *ss = cgdm->ss;
1825 MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
1826 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
1827 char *faceFlags = cgdm->faceFlags;
1828 int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1829 int gridFaces = gridSize - 1;
1831 ccgdm_pbvh_update(cgdm);
1834 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
1836 totface = ccgSubSurf_getNumFaces(ss);
1837 for(i = 0; i < totface; i++) {
1838 CCGFace *f = cgdm->faceMap[i].face;
1839 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1840 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1841 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1842 unsigned char *cp= NULL;
1846 drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1847 mat_nr= faceFlags[origIndex*2 + 1];
1855 flag = drawParams(tf, mcol!=NULL, mat_nr);
1856 else if (index != ORIGINDEX_NONE)
1857 flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
1859 flag= GPU_enable_material(mat_nr, NULL) ? 1:0;
1862 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
1863 if(tf) tf += gridFaces*gridFaces*numVerts;
1864 if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
1868 /* flag 1 == use vertex colors */
1870 if(flag==1) cp= (unsigned char*)mcol;
1871 mcol += gridFaces*gridFaces*numVerts*4;
1874 for (S=0; S<numVerts; S++) {
1875 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1879 glShadeModel(GL_SMOOTH);
1880 for (y=0; y<gridFaces; y++) {
1881 glBegin(GL_QUAD_STRIP);
1882 for (x=0; x<gridFaces; x++) {
1883 a = &faceGridData[(y+0)*gridSize + x];
1884 b = &faceGridData[(y+1)*gridSize + x];
1886 if(tf) glTexCoord2fv(tf->uv[0]);
1887 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1891 if(tf) glTexCoord2fv(tf->uv[1]);
1892 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1896 if(x != gridFaces-1) {
1902 a = &faceGridData[(y+0)*gridSize + x];
1903 b = &faceGridData[(y+1)*gridSize + x];
1905 if(tf) glTexCoord2fv(tf->uv[3]);
1906 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1910 if(tf) glTexCoord2fv(tf->uv[2]);
1911 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1921 glShadeModel(GL_FLAT);
1923 for (y=0; y<gridFaces; y++) {
1924 for (x=0; x<gridFaces; x++) {
1925 float *a_co = faceGridData[(y+0)*gridSize + x].co;
1926 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
1927 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
1928 float *d_co = faceGridData[(y+1)*gridSize + x].co;
1930 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
1932 if(tf) glTexCoord2fv(tf->uv[1]);
1933 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1936 if(tf) glTexCoord2fv(tf->uv[2]);
1937 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1940 if(tf) glTexCoord2fv(tf->uv[3]);
1941 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1944 if(tf) glTexCoord2fv(tf->uv[0]);
1945 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1958 static void cgdm_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
1960 cgdm_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
1963 static void cgdm_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1965 cgdm_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
1968 static void cgdm_drawUVEdges(DerivedMesh *dm)
1971 MFace *mf = dm->getTessFaceArray(dm);
1972 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
1977 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
1978 if(!(mf->flag&ME_HIDE)) {
1979 glVertex2fv(tf->uv[0]);
1980 glVertex2fv(tf->uv[1]);
1982 glVertex2fv(tf->uv[1]);
1983 glVertex2fv(tf->uv[2]);
1986 glVertex2fv(tf->uv[2]);
1987 glVertex2fv(tf->uv[0]);
1989 glVertex2fv(tf->uv[2]);
1990 glVertex2fv(tf->uv[3]);
1992 glVertex2fv(tf->uv[3]);
1993 glVertex2fv(tf->uv[0]);
2001 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs)) {
2002 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2003 CCGSubSurf *ss = cgdm->ss;
2005 int i, gridSize = ccgSubSurf_getGridSize(ss);
2006 char *faceFlags = cgdm->faceFlags;
2007 int gridFaces = gridSize - 1, totface;
2010 mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
2012 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
2015 totface = ccgSubSurf_getNumFaces(ss);
2016 for(i = 0; i < totface; i++) {
2017 CCGFace *f = cgdm->faceMap[i].face;
2018 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2019 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2021 unsigned char *cp= NULL;
2023 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2025 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
2026 else drawSmooth = 1;
2029 cp= (unsigned char*)mcol;
2030 mcol += gridFaces*gridFaces*numVerts*4;
2036 if(index == ORIGINDEX_NONE)
2037 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */
2038 else if (setDrawOptions)
2039 draw= setDrawOptions(userData, index, &drawSmooth);
2043 glEnable(GL_POLYGON_STIPPLE);
2044 glPolygonStipple(stipple_quarttone);
2047 for (S=0; S<numVerts; S++) {
2048 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2050 glShadeModel(GL_SMOOTH);
2051 for (y=0; y<gridFaces; y++) {
2053 glBegin(GL_QUAD_STRIP);
2054 for (x=0; x<gridFaces; x++) {
2055 a = &faceGridData[(y+0)*gridSize + x];
2056 b = &faceGridData[(y+1)*gridSize + x];
2058 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2061 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2065 if(x != gridFaces-1) {
2070 a = &faceGridData[(y+0)*gridSize + x];
2071 b = &faceGridData[(y+1)*gridSize + x];
2073 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2076 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2085 glShadeModel(GL_FLAT);
2087 for (y=0; y<gridFaces; y++) {
2088 for (x=0; x<gridFaces; x++) {
2089 float *a = faceGridData[(y+0)*gridSize + x].co;
2090 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2091 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2092 float *d = faceGridData[(y+1)*gridSize + x].co;
2094 ccgDM_glNormalFast(a, b, c, d);
2096 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2098 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2100 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2102 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2112 glDisable(GL_POLYGON_STIPPLE);
2117 static void cgdm_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2118 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2119 CCGSubSurf *ss = cgdm->ss;
2120 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2121 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2123 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2125 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2126 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2127 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2128 int index = ccgDM_getEdgeMapIndex(ss, e);
2130 glBegin(GL_LINE_STRIP);
2131 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2132 if (useAging && !(G.f&G_BACKBUFSEL)) {
2133 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2134 glColor3ub(0, ageCol>0?ageCol:0, 0);
2137 for (i=0; i<edgeSize-1; i++) {
2138 glVertex3fv(edgeData[i].co);
2139 glVertex3fv(edgeData[i+1].co);
2145 ccgEdgeIterator_free(ei);
2147 static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2148 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2149 CCGSubSurf *ss = cgdm->ss;
2150 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2151 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2153 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2155 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2156 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2157 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2158 int index = ccgDM_getEdgeMapIndex(ss, e);
2160 glBegin(GL_LINE_STRIP);
2161 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2162 for (i=0; i<edgeSize; i++) {
2163 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2165 if (useAging && !(G.f&G_BACKBUFSEL)) {
2166 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2167 glColor3ub(0, ageCol>0?ageCol:0, 0);
2170 glVertex3fv(edgeData[i].co);
2176 ccgEdgeIterator_free(ei);
2178 static void cgdm_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2179 CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2180 CCGSubSurf *ss = cgdm->ss;
2181 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2183 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2184 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2185 int index = ccgDM_getFaceMapIndex(ss, f);
2188 /* Face center data normal isn't updated atm. */
2189 DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2191 func(userData, index, vd->co, vd->no);
2195 ccgFaceIterator_free(fi);
2198 static void cgdm_release(DerivedMesh *dm) {
2199 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2201 if (DM_release(dm)) {
2202 /* Before freeing, need to update the displacement map */
2203 if(ccgdm->multires.modified) {
2204 /* Check that mmd still exists */
2205 if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2206 ccgdm->multires.mmd = NULL;
2207 if(ccgdm->multires.mmd)
2208 ccgdm->multires.update(dm);
2212 BLI_edgehash_free(ccgdm->ehash, NULL);
2214 if(ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);
2215 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
2216 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
2217 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
2218 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2219 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2220 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2221 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2222 MEM_freeN(ccgdm->edgeFlags);
2223 MEM_freeN(ccgdm->faceFlags);
2224 MEM_freeN(ccgdm->vertMap);
2225 MEM_freeN(ccgdm->edgeMap);
2226 MEM_freeN(ccgdm->faceMap);
2231 static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata,
2232 CustomData *pdata, int loopstart, int findex,
2233 int polyindex, int numTex, int numCol)
2240 int i, j, hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
2242 for(i=0; i < numTex; i++){
2243 texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
2244 texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
2246 texface->tpage = texpoly->tpage;
2247 texface->flag = texpoly->flag;
2248 texface->transp = texpoly->transp;
2249 texface->mode = texpoly->mode;
2250 texface->tile = texpoly->tile;
2251 texface->unwrap = texpoly->unwrap;
2253 mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
2254 for (j=0; j<4; j++, mloopuv++) {
2255 texface->uv[j][0] = mloopuv->uv[0];
2256 texface->uv[j][1] = mloopuv->uv[1];
2260 for(i=0; i < numCol; i++){
2261 mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i);
2262 mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
2264 for (j=0; j<4; j++, mloopcol++) {
2265 mcol[j].r = mloopcol->r;
2266 mcol[j].g = mloopcol->g;
2267 mcol[j].b = mloopcol->b;
2268 mcol[j].a = mloopcol->a;
2273 mloopcol = CustomData_get(ldata, loopstart, CD_WEIGHT_MLOOPCOL);
2274 mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
2276 for (j=0; j<4; j++, mloopcol++) {
2277 mcol[j].r = mloopcol->r;
2278 mcol[j].g = mloopcol->g;
2279 mcol[j].b = mloopcol->b;
2280 mcol[j].a = mloopcol->a;
2285 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2287 if(type == CD_ORIGINDEX) {
2288 /* create origindex on demand to save memory */
2289 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2290 CCGSubSurf *ss= cgdm->ss;
2292 int a, index, totnone, totorig;
2294 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2295 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2297 totorig = ccgSubSurf_getNumVerts(ss);
2298 totnone= dm->numVertData - totorig;
2300 /* original vertices are at the end */
2301 for(a=0; a<totnone; a++)
2302 origindex[a]= ORIGINDEX_NONE;
2304 for(index=0; index<totorig; index++, a++) {
2305 CCGVert *v = cgdm->vertMap[index].vert;
2306 origindex[a] = ccgDM_getVertMapIndex(cgdm->ss, v);
2312 return DM_get_vert_data_layer(dm, type);
2315 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2317 if(type == CD_ORIGINDEX) {
2318 /* create origindex on demand to save memory */
2319 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2320 CCGSubSurf *ss= cgdm->ss;
2322 int a, i, index, totnone, totorig, totedge;
2323 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2325 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2326 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2328 totedge= ccgSubSurf_getNumEdges(ss);
2329 totorig= totedge*(edgeSize - 1);
2330 totnone= dm->numEdgeData - totorig;
2332 /* original edges are at the end */
2333 for(a=0; a<totnone; a++)
2334 origindex[a]= ORIGINDEX_NONE;
2336 for(index=0; index<totedge; index++) {
2337 CCGEdge *e= cgdm->edgeMap[index].edge;
2338 int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2340 for(i = 0; i < edgeSize - 1; i++, a++)
2341 origindex[a]= mapIndex;
2347 return DM_get_edge_data_layer(dm, type);
2350 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2352 if(type == CD_ORIGINDEX) {
2353 /* create origindex on demand to save memory */
2354 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2355 CCGSubSurf *ss= cgdm->ss;
2357 int a, i, index, totface;
2358 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2360 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2361 origindex= DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
2363 totface= ccgSubSurf_getNumFaces(ss);
2365 for(a=0, index=0; index<totface; index++) {
2366 CCGFace *f = cgdm->faceMap[index].face;
2367 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2368 int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2370 for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2371 origindex[a]= mapIndex;
2377 return DM_get_tessface_data_layer(dm, type);
2380 static int ccgDM_getNumGrids(DerivedMesh *dm)
2382 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2383 int index, numFaces, numGrids;
2385 numFaces= ccgSubSurf_getNumFaces(cgdm->ss);
2388 for(index=0; index<numFaces; index++) {
2389 CCGFace *f = cgdm->faceMap[index].face;
2390 numGrids += ccgSubSurf_getFaceNumVerts(f);
2396 static int ccgDM_getGridSize(DerivedMesh *dm)
2398 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2399 return ccgSubSurf_getGridSize(cgdm->ss);
2402 static int cgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2406 int i, j= 0, numFaces, fIndex, numEdges= 0;
2408 e = ccgSubSurf_getFaceEdge(ss, f, S);
2409 numFaces = ccgSubSurf_getEdgeNumFaces(e);
2414 for(i = 0; i < numFaces; i++) {
2415 adjf = ccgSubSurf_getEdgeFace(e, i);
2418 numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2419 for(j = 0; j < numEdges; j++)
2420 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2428 fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2430 return gridOffset[fIndex] + (j + offset)%numEdges;
2433 static void ccgdm_create_grids(DerivedMesh *dm)
2435 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2436 CCGSubSurf *ss= cgdm->ss;
2437 DMGridData **gridData;
2438 DMGridAdjacency *gridAdjacency, *adj;
2439 CCGFace **gridFaces;
2441 int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2446 numGrids = ccgDM_getNumGrids(dm);
2447 numFaces = ccgSubSurf_getNumFaces(ss);
2448 /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/
2450 /* compute offset into grid array for each face */
2451 gridOffset = MEM_mallocN(sizeof(int)*numFaces, "cgdm.gridOffset");
2453 for(gIndex = 0, index = 0; index < numFaces; index++) {
2454 CCGFace *f = cgdm->faceMap[index].face;
2455 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2457 gridOffset[index] = gIndex;
2461 /* compute grid data */
2462 gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "cgdm.gridData");
2463 gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "cgdm.gridAdjacency");
2464 gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "cgdm.gridFaces");
2466 for(gIndex = 0, index = 0; index < numFaces; index++) {
2467 CCGFace *f = cgdm->faceMap[index].face;
2468 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2470 for(S = 0; S < numVerts; S++, gIndex++) {
2471 int prevS = (S - 1 + numVerts) % numVerts;
2472 int nextS = (S + 1 + numVerts) % numVerts;
2474 gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2475 gridFaces[gIndex] = f;
2477 adj = &gridAdjacency[gIndex];
2479 adj->index[0] = gIndex - S + nextS;
2480 adj->rotation[0] = 3;
2481 adj->index[1] = cgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2482 adj->rotation[1] = 1;
2483 adj->index[2] = cgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2484 adj->rotation[2] = 3;
2485 adj->index[3] = gIndex - S + prevS;
2486 adj->rotation[3] = 1;
2490 cgdm->gridData = gridData;
2491 cgdm->gridFaces = gridFaces;
2492 cgdm->gridAdjacency = gridAdjacency;
2493 cgdm->gridOffset = gridOffset;
2496 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2498 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2500 ccgdm_create_grids(dm);
2501 return cgdm->gridData;
2504 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2506 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2508 ccgdm_create_grids(dm);
2509 return cgdm->gridAdjacency;
2512 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2514 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2516 ccgdm_create_grids(dm);
2517 return cgdm->gridOffset;
2520 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2522 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2524 if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2527 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2528 me->totvert, me->totface);
2534 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2536 MultiresModifierData *mmd= ccgdm->multires.mmd;
2538 /* both of multires and subsurm modifiers are CCG, but
2539 grids should only be used when sculpting on multires */
2546 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2548 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2549 int gridSize, numGrids, grid_pbvh;
2559 grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2561 if(ob->sculpt->pbvh) {
2563 /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2564 but this can be freed on ccgdm release, this updates the pointers
2565 when the ccgdm gets remade, the assumption is that the topology
2567 ccgdm_create_grids(dm);
2568 BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2571 ccgdm->pbvh = ob->sculpt->pbvh;
2577 /* no pbvh exists yet, we need to create one. only in case of multires
2578 we build a pbvh over the modified mesh, in other cases the base mesh
2579 is being sculpted, so we build a pbvh from that. */
2581 ccgdm_create_grids(dm);
2583 gridSize = ccgDM_getGridSize(dm);
2584 numGrids = ccgDM_getNumGrids(dm);
2586 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2587 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2588 numGrids, gridSize, (void**)ccgdm->gridFaces);
2589 } else if(ob->type == OB_MESH) {
2591 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2592 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2593 me->totface, me->totvert);
2599 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2600 int drawInteriorEdges,
2604 CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "cgdm");
2605 CCGVertIterator *vi;
2606 CCGEdgeIterator *ei;
2607 CCGFaceIterator *fi;
2608 int index, totvert, totedge, totface;
2610 int vertNum, edgeNum, faceNum;
2611 int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex; /* *edgeOrigIndex - as yet, unused */
2614 int *loopidx = NULL, *vertidx = NULL;
2615 BLI_array_declare(loopidx);
2616 BLI_array_declare(vertidx);
2617 int loopindex, loopindex2;
2618 int edgeSize, has_edge_origindex;
2620 int gridFaces, gridCuts;
2621 /*int gridSideVerts;*/
2624 int gridInternalEdges;
2626 WeightTable wtable = {0};
2628 MEdge *medge = NULL;
2629 MFace *mface = NULL;
2630 MPoly *mpoly = NULL;
2632 DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2633 ccgSubSurf_getNumFinalVerts(ss),
2634 ccgSubSurf_getNumFinalEdges(ss),
2635 ccgSubSurf_getNumFinalFaces(ss),
2636 ccgSubSurf_getNumFinalFaces(ss)*4,
2637 ccgSubSurf_getNumFinalFaces(ss));
2639 numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
2640 numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
2642 if (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex)
2643 CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
2644 else if (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol)
2645 CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
2647 ccgdm->dm.getMinMax = cgdm_getMinMax;
2648 ccgdm->dm.getNumVerts = cgdm_getNumVerts;
2649 ccgdm->dm.getNumEdges = cgdm_getNumEdges;
2650 ccgdm->dm.getNumTessFaces = cgdm_getNumTessFaces;
2651 ccgdm->dm.getNumFaces = cgdm_getNumTessFaces;
2653 ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2654 ccgdm->dm.getPBVH = ccgDM_getPBVH;
2656 ccgdm->dm.getVert = ccgDM_getFinalVert;
2657 ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2658 ccgdm->dm.getTessFace = ccgDM_getFinalFace;
2659 ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2660 ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2661 ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2662 ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2663 ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
2664 ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
2665 ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
2666 ccgdm->dm.getVertData = DM_get_vert_data;
2667 ccgdm->dm.getEdgeData = DM_get_edge_data;
2668 ccgdm->dm.getTessFaceData = DM_get_face_data;
2669 ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2670 ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2671 ccgdm->dm.getTessFaceDataArray = ccgDM_get_face_data_layer;
2672 ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2673 ccgdm->dm.getGridSize = ccgDM_getGridSize;
2674 ccgdm->dm.getGridData = ccgDM_getGridData;
2675 ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2676 ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2677 ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2678 ccgdm->dm.getPBVH = ccgDM_getPBVH;
2680 ccgdm->dm.getTessFace = ccgDM_getFinalFace;
2681 ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2682 ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2683 ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
2684 ccgdm->dm.getVertData = DM_get_vert_data;
2685 ccgdm->dm.getEdgeData = DM_get_edge_data;
2686 ccgdm->dm.getTessFaceData = DM_get_face_data;
2687 ccgdm->dm.getVertDataArray = DM_get_vert_data_layer;
2688 ccgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
2689 ccgdm->dm.getTessFaceDataArray = DM_get_tessface_data_layer;
2691 ccgdm->dm.getVertCos = cgdm_getVertCos;
2692 ccgdm->dm.foreachMappedVert = cgdm_foreachMappedVert;
2693 ccgdm->dm.foreachMappedEdge = cgdm_foreachMappedEdge;
2694 ccgdm->dm.foreachMappedFaceCenter = cgdm_foreachMappedFaceCenter;
2696 ccgdm->dm.drawVerts = ccgDM_drawVerts;
2697 ccgdm->dm.drawEdges = ccgDM_drawEdges;
2698 ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2699 ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2700 ccgdm->dm.drawFacesColored = cgdm_drawFacesColored;
2701 ccgdm->dm.drawFacesTex = cgdm_drawFacesTex;
2702 ccgdm->dm.drawFacesGLSL = cgdm_drawFacesGLSL;
2703 ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2704 ccgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex;
2705 ccgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL;
2706 ccgdm->dm.drawUVEdges = cgdm_drawUVEdges;
2708 ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;
2709 ccgdm->dm.drawMappedEdges = cgdm_drawMappedEdges;
2711 ccgdm->dm.release = cgdm_release;
2714 ccgdm->drawInteriorEdges = drawInteriorEdges;
2715 ccgdm->useSubsurfUv = useSubsurfUv;
2717 totvert = ccgSubSurf_getNumVerts(ss);
2718 ccgdm->vertMap = MEM_callocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2719 vi = ccgSubSurf_getVertIterator(ss);
2720 for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2721 CCGVert *v = ccgVertIterator_getCurrent(vi);
2723 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2725 ccgVertIterator_free(vi);
2727 totedge = ccgSubSurf_getNumEdges(ss);
2728 ccgdm->edgeMap = MEM_callocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2729 ei = ccgSubSurf_getEdgeIterator(ss);
2730 for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2731 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2733 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2736 totface = ccgSubSurf_getNumFaces(ss);
2737 ccgdm->faceMap = MEM_callocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2738 fi = ccgSubSurf_getFaceIterator(ss);
2739 for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2740 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2742 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2744 ccgFaceIterator_free(fi);
2746 ccgdm->reverseFaceMap = MEM_callocN(sizeof(int)*ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap");
2748 edgeSize = ccgSubSurf_getEdgeSize(ss);
2749 gridSize = ccgSubSurf_getGridSize(ss);
2750 gridFaces = gridSize - 1;
2751 gridCuts = gridSize - 2;
2752 /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
2753 gridSideEdges = gridSize - 1;
2754 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
2760 /* mvert = dm->getVertArray(dm); - as yet unused */
2761 medge = dm->getEdgeArray(dm);
2762 mface = dm->getTessFaceArray(dm);
2764 mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2765 base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2768 edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "faceFlags");
2769 faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
2771 vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2772 /*edgeOrigIndex = DM_get_edge_data_layer(&cgdm->dm, CD_ORIGINDEX);*/
2773 faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2775 polyOrigIndex = DM_get_face_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2777 if (!CustomData_has_layer(&ccgdm->dm.faceData, CD_MCOL))
2778 DM_add_tessface_layer(&ccgdm->dm, CD_MCOL, CD_CALLOC, NULL);
2780 mcol = DM_get_tessface_data_layer(&ccgdm->dm, CD_MCOL);
2781 has_edge_origindex = CustomData_has_layer(&ccgdm->dm.edgeData, CD_ORIGINDEX);
2784 loopindex = loopindex2 = 0; //current loop index
2785 for (index = 0; index < totface; index++) {
2786 CCGFace *f = ccgdm->faceMap[index].face;
2787 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2788 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2789 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2790 int g2_wid = gridCuts+2;
2794 origIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
2796 w = get_ss_weights(&wtable, gridCuts, numVerts);
2798 ccgdm->faceMap[index].startVert = vertNum;
2799 ccgdm->faceMap[index].startEdge = edgeNum;
2800 ccgdm->faceMap[index].startFace = faceNum;
2802 faceFlags[0] = mpoly ? mpoly[origIndex].flag : 0;
2803 faceFlags[1] = mpoly ? mpoly[origIndex].mat_nr : 0;
2806 /* set the face base vert */
2807 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2809 BLI_array_empty(loopidx);
2810 for (s=0; s<numVerts; s++) {
2811 BLI_array_growone(loopidx);
2812 loopidx[s] = loopindex++;
2815 BLI_array_empty(vertidx);
2816 for(s = 0; s < numVerts; s++) {
2817 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, s);
2819 BLI_array_growone(vertidx);
2820 vertidx[s] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2824 /*I think this is for interpolating the center vert?*/
2825 w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1);
2826 DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
2828 if (vertOrigIndex) {
2829 *vertOrigIndex = ORIGINDEX_NONE;
2835 /*interpolate per-vert data*/
2836 for(s = 0; s < numVerts; s++) {
2837 for(x = 1; x < gridFaces; x++) {
2838 w2 = w + s*numVerts*g2_wid*g2_wid + x*numVerts;
2839 DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
2842 if (vertOrigIndex) {
2843 *vertOrigIndex = ORIGINDEX_NONE;
2851 /*interpolate per-vert data*/
2852 for(s = 0; s < numVerts; s++) {
2853 for(y = 1; y < gridFaces; y++) {
2854 for(x = 1; x < gridFaces; x++) {
2855 w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
2856 DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
2859 if (vertOrigIndex) {
2860 *vertOrigIndex = ORIGINDEX_NONE;
2869 if (has_edge_origindex) {
2870 for(i = 0; i < numFinalEdges; ++i)
2871 *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
2872 CD_ORIGINDEX) = ORIGINDEX_NONE;
2875 for (s=0; s<numVerts; s++) {
2876 /*interpolate per-face data*/
2877 for (y=0; y<gridFaces; y++) {
2878 for (x=0; x<gridFaces; x++) {
2879 w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
2880 CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
2881 loopidx, w2, NULL, numVerts, loopindex2);