|
Blender
V2.59
|
00001 /* 00002 * $Id: subsurf_ccg.c 38298 2011-07-11 09:05:10Z blendix $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2005 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include <stdlib.h> 00036 #include <string.h> 00037 #include <stdio.h> 00038 #include <math.h> 00039 #include <float.h> 00040 00041 #include "MEM_guardedalloc.h" 00042 00043 #include "DNA_mesh_types.h" 00044 #include "DNA_meshdata_types.h" 00045 #include "DNA_modifier_types.h" 00046 #include "DNA_object_types.h" 00047 #include "DNA_scene_types.h" 00048 00049 #include "BLI_blenlib.h" 00050 #include "BLI_edgehash.h" 00051 #include "BLI_math.h" 00052 #include "BLI_memarena.h" 00053 #include "BLI_pbvh.h" 00054 #include "BLI_utildefines.h" 00055 00056 #include "BKE_cdderivedmesh.h" 00057 #include "BKE_global.h" 00058 #include "BKE_mesh.h" 00059 #include "BKE_modifier.h" 00060 #include "BKE_paint.h" 00061 #include "BKE_scene.h" 00062 #include "BKE_subsurf.h" 00063 00064 00065 #include "BIF_gl.h" 00066 #include "BIF_glutil.h" 00067 00068 #include "GPU_draw.h" 00069 #include "GPU_extensions.h" 00070 #include "GPU_material.h" 00071 00072 #include "CCGSubSurf.h" 00073 00074 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v); 00075 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e); 00076 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f); 00077 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm); 00078 00080 00081 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) { 00082 return BLI_memarena_alloc(a, numBytes); 00083 } 00084 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) { 00085 void *p2 = BLI_memarena_alloc(a, newSize); 00086 if (ptr) { 00087 memcpy(p2, ptr, oldSize); 00088 } 00089 return p2; 00090 } 00091 static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr)) { 00092 } 00093 static void arena_release(CCGAllocatorHDL a) { 00094 BLI_memarena_free(a); 00095 } 00096 00097 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int UNUSED(useFlatSubdiv)) { 00098 CCGMeshIFC ifc; 00099 CCGSubSurf *ccgSS; 00100 00101 /* subdivLevels==0 is not allowed */ 00102 subdivLevels = MAX2(subdivLevels, 1); 00103 00104 if (prevSS) { 00105 int oldUseAging; 00106 00107 useAging = !!useAging; 00108 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL); 00109 00110 if (oldUseAging!=useAging) { 00111 ccgSubSurf_free(prevSS); 00112 } else { 00113 ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels); 00114 00115 return prevSS; 00116 } 00117 } 00118 00119 if (useAging) { 00120 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12; 00121 } else { 00122 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8; 00123 } 00124 ifc.vertDataSize = sizeof(DMGridData); 00125 00126 if (useArena) { 00127 CCGAllocatorIFC allocatorIFC; 00128 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16), "subsurf arena"); 00129 00130 allocatorIFC.alloc = arena_alloc; 00131 allocatorIFC.realloc = arena_realloc; 00132 allocatorIFC.free = arena_free; 00133 allocatorIFC.release = arena_release; 00134 00135 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator); 00136 } else { 00137 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL); 00138 } 00139 00140 if (useAging) { 00141 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8); 00142 } 00143 00144 ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(DMGridData, no)); 00145 00146 return ccgSS; 00147 } 00148 00149 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) { 00150 CCGVert *v0 = ccgSubSurf_getEdgeVert0(e); 00151 CCGVert *v1 = ccgSubSurf_getEdgeVert1(e); 00152 int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0)); 00153 int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1)); 00154 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e)); 00155 00156 if (x==0) { 00157 return v0idx; 00158 } else if (x==edgeSize-1) { 00159 return v1idx; 00160 } else { 00161 return edgeBase + x-1; 00162 } 00163 } 00164 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) { 00165 int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f)); 00166 int numVerts = ccgSubSurf_getFaceNumVerts(f); 00167 00168 if (x==gridSize-1 && y==gridSize-1) { 00169 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); 00170 return *((int*) ccgSubSurf_getVertUserData(ss, v)); 00171 } else if (x==gridSize-1) { 00172 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); 00173 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S); 00174 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e)); 00175 if (v==ccgSubSurf_getEdgeVert0(e)) { 00176 return edgeBase + (gridSize-1-y)-1; 00177 } else { 00178 return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1); 00179 } 00180 } else if (y==gridSize-1) { 00181 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); 00182 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts); 00183 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e)); 00184 if (v==ccgSubSurf_getEdgeVert0(e)) { 00185 return edgeBase + (gridSize-1-x)-1; 00186 } else { 00187 return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1); 00188 } 00189 } else if (x==0 && y==0) { 00190 return faceBase; 00191 } else if (x==0) { 00192 S = (S+numVerts-1)%numVerts; 00193 return faceBase + 1 + (gridSize-2)*S + (y-1); 00194 } else if (y==0) { 00195 return faceBase + 1 + (gridSize-2)*S + (x-1); 00196 } else { 00197 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1); 00198 } 00199 } 00200 00201 static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) { 00202 unsigned int *fv = &mf->v1; 00203 UvMapVert *v, *nv; 00204 int j, nverts= mf->v4? 4: 3; 00205 00206 for (j=0; j<nverts; j++, fv++) { 00207 for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) { 00208 if (v->separate) 00209 nv= v; 00210 if (v->f == fi) 00211 break; 00212 } 00213 00214 fverts[j]= SET_INT_IN_POINTER(nv->f*4 + nv->tfindex); 00215 } 00216 } 00217 00218 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MTFace *tface) { 00219 MFace *mface = dm->getFaceArray(dm); 00220 MVert *mvert = dm->getVertArray(dm); 00221 int totvert = dm->getNumVerts(dm); 00222 int totface = dm->getNumFaces(dm); 00223 int i, j, seam; 00224 UvMapVert *v; 00225 UvVertMap *vmap; 00226 float limit[2]; 00227 CCGVertHDL fverts[4]; 00228 EdgeHash *ehash; 00229 float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss); 00230 00231 limit[0]= limit[1]= STD_UV_CONNECT_LIMIT; 00232 vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit); 00233 if (!vmap) 00234 return 0; 00235 00236 ccgSubSurf_initFullSync(ss); 00237 00238 /* create vertices */ 00239 for (i=0; i<totvert; i++) { 00240 if (!get_uv_map_vert(vmap, i)) 00241 continue; 00242 00243 for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next) 00244 if (v->separate) 00245 break; 00246 00247 seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED); 00248 00249 for (v=get_uv_map_vert(vmap, i); v; v=v->next) { 00250 if (v->separate) { 00251 CCGVert *ssv; 00252 CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex); 00253 float uv[3]; 00254 00255 uv[0]= (tface+v->f)->uv[v->tfindex][0]; 00256 uv[1]= (tface+v->f)->uv[v->tfindex][1]; 00257 uv[2]= 0.0f; 00258 00259 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv); 00260 } 00261 } 00262 } 00263 00264 /* create edges */ 00265 ehash = BLI_edgehash_new(); 00266 00267 for (i=0; i<totface; i++) { 00268 MFace *mf = &((MFace*) mface)[i]; 00269 int nverts= mf->v4? 4: 3; 00270 CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i)); 00271 unsigned int *fv = &mf->v1; 00272 00273 get_face_uv_map_vert(vmap, mf, i, fverts); 00274 00275 for (j=0; j<nverts; j++) { 00276 int v0 = GET_INT_FROM_POINTER(fverts[j]); 00277 int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]); 00278 MVert *mv0 = mvert + *(fv+j); 00279 MVert *mv1 = mvert + *(fv+((j+1)%nverts)); 00280 00281 if (!BLI_edgehash_haskey(ehash, v0, v1)) { 00282 CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j); 00283 CCGEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j); 00284 float crease; 00285 00286 if ((mv0->flag&mv1->flag) & ME_VERT_MERGED) 00287 crease = creaseFactor; 00288 else 00289 crease = ccgSubSurf_getEdgeCrease(orige); 00290 00291 ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e); 00292 BLI_edgehash_insert(ehash, v0, v1, NULL); 00293 } 00294 } 00295 } 00296 00297 BLI_edgehash_free(ehash, NULL); 00298 00299 /* create faces */ 00300 for (i=0; i<totface; i++) { 00301 MFace *mf = &((MFace*) mface)[i]; 00302 int nverts= mf->v4? 4: 3; 00303 CCGFace *f; 00304 00305 get_face_uv_map_vert(vmap, mf, i, fverts); 00306 ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f); 00307 } 00308 00309 free_uv_vert_map(vmap); 00310 ccgSubSurf_processSync(ss); 00311 00312 return 1; 00313 } 00314 00315 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n) 00316 { 00317 CCGSubSurf *uvss; 00318 CCGFace **faceMap; 00319 MTFace *tf; 00320 CCGFaceIterator *fi; 00321 int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S; 00322 MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n); 00323 MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n); 00324 00325 if(!dmtface || !tface) 00326 return; 00327 00328 /* create a CCGSubSurf from uv's */ 00329 uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0); 00330 00331 if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) { 00332 ccgSubSurf_free(uvss); 00333 return; 00334 } 00335 00336 /* get some info from CCGSubSurf */ 00337 totface = ccgSubSurf_getNumFaces(uvss); 00338 /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/ 00339 gridSize = ccgSubSurf_getGridSize(uvss); 00340 gridFaces = gridSize - 1; 00341 00342 /* make a map from original faces to CCGFaces */ 00343 faceMap = MEM_mallocN(totface*sizeof(*faceMap), "facemapuv"); 00344 00345 fi = ccgSubSurf_getFaceIterator(uvss); 00346 for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { 00347 CCGFace *f = ccgFaceIterator_getCurrent(fi); 00348 faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(uvss, f))] = f; 00349 } 00350 ccgFaceIterator_free(fi); 00351 00352 /* load coordinates from uvss into tface */ 00353 tf= tface; 00354 00355 for(index = 0; index < totface; index++) { 00356 CCGFace *f = faceMap[index]; 00357 int numVerts = ccgSubSurf_getFaceNumVerts(f); 00358 00359 for (S=0; S<numVerts; S++) { 00360 DMGridData *faceGridData= ccgSubSurf_getFaceGridDataArray(uvss, f, S); 00361 00362 for(y = 0; y < gridFaces; y++) { 00363 for(x = 0; x < gridFaces; x++) { 00364 float *a = faceGridData[(y + 0)*gridSize + x + 0].co; 00365 float *b = faceGridData[(y + 0)*gridSize + x + 1].co; 00366 float *c = faceGridData[(y + 1)*gridSize + x + 1].co; 00367 float *d = faceGridData[(y + 1)*gridSize + x + 0].co; 00368 00369 tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1]; 00370 tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1]; 00371 tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1]; 00372 tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1]; 00373 00374 tf++; 00375 } 00376 } 00377 } 00378 } 00379 00380 ccgSubSurf_free(uvss); 00381 MEM_freeN(faceMap); 00382 } 00383 00384 /* face weighting */ 00385 static void calc_ss_weights(int gridFaces, 00386 FaceVertWeight **qweight, FaceVertWeight **tweight) 00387 { 00388 FaceVertWeight *qw, *tw; 00389 int x, y, j; 00390 int numWeights = gridFaces * gridFaces; 00391 00392 *tweight = MEM_mallocN(sizeof(**tweight) * numWeights, "ssTriWeight"); 00393 *qweight = MEM_mallocN(sizeof(**qweight) * numWeights, "ssQuadWeight"); 00394 00395 qw = *qweight; 00396 tw = *tweight; 00397 00398 for (y = 0; y < gridFaces; y++) { 00399 for (x = 0; x < gridFaces; x++) { 00400 for (j = 0; j < 4; j++) { 00401 int fx = x + (j == 2 || j == 3); 00402 int fy = y + (j == 1 || j == 2); 00403 float x_v = (float) fx / gridFaces; 00404 float y_v = (float) fy / gridFaces; 00405 float tx_v = (1.0f - x_v), ty_v = (1.0f - y_v); 00406 float center = (1.0f / 3.0f) * tx_v * ty_v; 00407 00408 (*tw)[j][0] = center + 0.5f * tx_v * y_v; 00409 (*tw)[j][2] = center + 0.5f * x_v * ty_v; 00410 (*tw)[j][1] = 1.0f - (*tw)[j][0] - (*tw)[j][2]; 00411 (*tw)[j][3] = 0.0f; 00412 00413 tx_v *= 0.5f; 00414 ty_v *= 0.5f; 00415 00416 (*qw)[j][3] = tx_v * ty_v; 00417 (*qw)[j][0] = (*qw)[j][3] + tx_v * y_v; 00418 (*qw)[j][2] = (*qw)[j][3] + x_v * ty_v; 00419 (*qw)[j][1] = 1.0f - (*qw)[j][0] - (*qw)[j][2] - (*qw)[j][3]; 00420 00421 } 00422 tw++; 00423 qw++; 00424 } 00425 } 00426 } 00427 00428 static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, 00429 float (*vertexCos)[3], int useFlatSubdiv) 00430 { 00431 float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss); 00432 CCGVertHDL fVerts[4]; 00433 int totvert = dm->getNumVerts(dm); 00434 int totedge = dm->getNumEdges(dm); 00435 int totface = dm->getNumFaces(dm); 00436 int i; 00437 int *index; 00438 MVert *mvert = dm->getVertArray(dm); 00439 MEdge *medge = dm->getEdgeArray(dm); 00440 MFace *mface = dm->getFaceArray(dm); 00441 MVert *mv; 00442 MEdge *me; 00443 MFace *mf; 00444 00445 ccgSubSurf_initFullSync(ss); 00446 00447 mv = mvert; 00448 index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX); 00449 for(i = 0; i < totvert; i++, mv++) { 00450 CCGVert *v; 00451 00452 if(vertexCos) { 00453 ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v); 00454 } else { 00455 ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v); 00456 } 00457 00458 ((int*)ccgSubSurf_getVertUserData(ss, v))[1] = (index)? *index++: i; 00459 } 00460 00461 me = medge; 00462 index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX); 00463 for(i = 0; i < totedge; i++, me++) { 00464 CCGEdge *e; 00465 float crease; 00466 00467 crease = useFlatSubdiv ? creaseFactor : 00468 me->crease * creaseFactor / 255.0f; 00469 00470 ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1), 00471 SET_INT_IN_POINTER(me->v2), crease, &e); 00472 00473 ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index)? *index++: i; 00474 } 00475 00476 mf = mface; 00477 index = (int *)dm->getFaceDataArray(dm, CD_ORIGINDEX); 00478 for (i = 0; i < totface; i++, mf++) { 00479 CCGFace *f; 00480 00481 fVerts[0] = SET_INT_IN_POINTER(mf->v1); 00482 fVerts[1] = SET_INT_IN_POINTER(mf->v2); 00483 fVerts[2] = SET_INT_IN_POINTER(mf->v3); 00484 fVerts[3] = SET_INT_IN_POINTER(mf->v4); 00485 00486 // this is very bad, means mesh is internally consistent. 00487 // it is not really possible to continue without modifying 00488 // other parts of code significantly to handle missing faces. 00489 // since this really shouldn't even be possible we just bail. 00490 if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), fVerts[3] ? 4 : 3, 00491 fVerts, &f) == eCCGError_InvalidValue) { 00492 static int hasGivenError = 0; 00493 00494 if(!hasGivenError) { 00495 //XXX error("Unrecoverable error in SubSurf calculation," 00496 // " mesh is inconsistent."); 00497 00498 hasGivenError = 1; 00499 } 00500 00501 return; 00502 } 00503 00504 ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = (index)? *index++: i; 00505 } 00506 00507 ccgSubSurf_processSync(ss); 00508 } 00509 00510 /***/ 00511 00512 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v) { 00513 return ((int*) ccgSubSurf_getVertUserData(ss, v))[1]; 00514 } 00515 00516 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e) { 00517 return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1]; 00518 } 00519 00520 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) { 00521 return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1]; 00522 } 00523 00524 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { 00525 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00526 CCGSubSurf *ss = ccgdm->ss; 00527 CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss); 00528 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); 00529 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); 00530 int i, edgeSize = ccgSubSurf_getEdgeSize(ss); 00531 int gridSize = ccgSubSurf_getGridSize(ss); 00532 00533 if (!ccgSubSurf_getNumVerts(ss)) 00534 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0; 00535 00536 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { 00537 CCGVert *v = ccgVertIterator_getCurrent(vi); 00538 float *co = ccgSubSurf_getVertData(ss, v); 00539 00540 DO_MINMAX(co, min_r, max_r); 00541 } 00542 00543 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { 00544 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); 00545 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); 00546 00547 for (i=0; i<edgeSize; i++) 00548 DO_MINMAX(edgeData[i].co, min_r, max_r); 00549 } 00550 00551 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { 00552 CCGFace *f = ccgFaceIterator_getCurrent(fi); 00553 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); 00554 00555 for (S=0; S<numVerts; S++) { 00556 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); 00557 00558 for (y=0; y<gridSize; y++) 00559 for (x=0; x<gridSize; x++) 00560 DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r); 00561 } 00562 } 00563 00564 ccgFaceIterator_free(fi); 00565 ccgEdgeIterator_free(ei); 00566 ccgVertIterator_free(vi); 00567 } 00568 static int ccgDM_getNumVerts(DerivedMesh *dm) { 00569 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00570 00571 return ccgSubSurf_getNumFinalVerts(ccgdm->ss); 00572 } 00573 static int ccgDM_getNumEdges(DerivedMesh *dm) { 00574 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00575 00576 return ccgSubSurf_getNumFinalEdges(ccgdm->ss); 00577 } 00578 static int ccgDM_getNumFaces(DerivedMesh *dm) { 00579 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00580 00581 return ccgSubSurf_getNumFinalFaces(ccgdm->ss); 00582 } 00583 00584 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) 00585 { 00586 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00587 CCGSubSurf *ss = ccgdm->ss; 00588 DMGridData *vd; 00589 int i; 00590 00591 memset(mv, 0, sizeof(*mv)); 00592 00593 if((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) { 00594 /* this vert comes from face data */ 00595 int lastface = ccgSubSurf_getNumFaces(ss) - 1; 00596 CCGFace *f; 00597 int x, y, grid, numVerts; 00598 int offset; 00599 int gridSize = ccgSubSurf_getGridSize(ss); 00600 int gridSideVerts; 00601 int gridInternalVerts; 00602 int gridSideEnd; 00603 int gridInternalEnd; 00604 00605 i = 0; 00606 while(i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert) 00607 ++i; 00608 00609 f = ccgdm->faceMap[i].face; 00610 numVerts = ccgSubSurf_getFaceNumVerts(f); 00611 00612 gridSideVerts = gridSize - 2; 00613 gridInternalVerts = gridSideVerts * gridSideVerts; 00614 00615 gridSideEnd = 1 + numVerts * gridSideVerts; 00616 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts; 00617 00618 offset = vertNum - ccgdm->faceMap[i].startVert; 00619 if(offset < 1) { 00620 vd = ccgSubSurf_getFaceCenterData(f); 00621 copy_v3_v3(mv->co, vd->co); 00622 normal_float_to_short_v3(mv->no, vd->no); 00623 } else if(offset < gridSideEnd) { 00624 offset -= 1; 00625 grid = offset / gridSideVerts; 00626 x = offset % gridSideVerts + 1; 00627 vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x); 00628 copy_v3_v3(mv->co, vd->co); 00629 normal_float_to_short_v3(mv->no, vd->no); 00630 } else if(offset < gridInternalEnd) { 00631 offset -= gridSideEnd; 00632 grid = offset / gridInternalVerts; 00633 offset %= gridInternalVerts; 00634 y = offset / gridSideVerts + 1; 00635 x = offset % gridSideVerts + 1; 00636 vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y); 00637 copy_v3_v3(mv->co, vd->co); 00638 normal_float_to_short_v3(mv->no, vd->no); 00639 } 00640 } else if((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) { 00641 /* this vert comes from edge data */ 00642 CCGEdge *e; 00643 int lastedge = ccgSubSurf_getNumEdges(ss) - 1; 00644 int x; 00645 00646 i = 0; 00647 while(i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert) 00648 ++i; 00649 00650 e = ccgdm->edgeMap[i].edge; 00651 00652 x = vertNum - ccgdm->edgeMap[i].startVert + 1; 00653 vd = ccgSubSurf_getEdgeData(ss, e, x); 00654 copy_v3_v3(mv->co, vd->co); 00655 normal_float_to_short_v3(mv->no, vd->no); 00656 } else { 00657 /* this vert comes from vert data */ 00658 CCGVert *v; 00659 i = vertNum - ccgdm->vertMap[0].startVert; 00660 00661 v = ccgdm->vertMap[i].vert; 00662 vd = ccgSubSurf_getVertData(ss, v); 00663 copy_v3_v3(mv->co, vd->co); 00664 normal_float_to_short_v3(mv->no, vd->no); 00665 } 00666 } 00667 00668 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float co_r[3]) 00669 { 00670 MVert mvert; 00671 00672 ccgDM_getFinalVert(dm, vertNum, &mvert); 00673 VECCOPY(co_r, mvert.co); 00674 } 00675 00676 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3]) 00677 { 00678 MVert mvert; 00679 00680 ccgDM_getFinalVert(dm, vertNum, &mvert); 00681 normal_short_to_float_v3(no_r, mvert.no); 00682 } 00683 00684 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med) 00685 { 00686 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00687 CCGSubSurf *ss = ccgdm->ss; 00688 int i; 00689 00690 memset(med, 0, sizeof(*med)); 00691 00692 if(edgeNum < ccgdm->edgeMap[0].startEdge) { 00693 /* this edge comes from face data */ 00694 int lastface = ccgSubSurf_getNumFaces(ss) - 1; 00695 CCGFace *f; 00696 int x, y, grid /*, numVerts*/; 00697 int offset; 00698 int gridSize = ccgSubSurf_getGridSize(ss); 00699 int edgeSize = ccgSubSurf_getEdgeSize(ss); 00700 int gridSideEdges; 00701 int gridInternalEdges; 00702 00703 i = 0; 00704 while(i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge) 00705 ++i; 00706 00707 f = ccgdm->faceMap[i].face; 00708 /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/ 00709 00710 gridSideEdges = gridSize - 1; 00711 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 00712 00713 offset = edgeNum - ccgdm->faceMap[i].startEdge; 00714 grid = offset / (gridSideEdges + gridInternalEdges); 00715 offset %= (gridSideEdges + gridInternalEdges); 00716 00717 if(offset < gridSideEdges) { 00718 x = offset; 00719 med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize); 00720 med->v2 = getFaceIndex(ss, f, grid, x+1, 0, edgeSize, gridSize); 00721 } else { 00722 offset -= gridSideEdges; 00723 x = (offset / 2) / gridSideEdges + 1; 00724 y = (offset / 2) % gridSideEdges; 00725 if(offset % 2 == 0) { 00726 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize); 00727 med->v2 = getFaceIndex(ss, f, grid, x, y+1, edgeSize, gridSize); 00728 } else { 00729 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize); 00730 med->v2 = getFaceIndex(ss, f, grid, y+1, x, edgeSize, gridSize); 00731 } 00732 } 00733 } else { 00734 /* this vert comes from edge data */ 00735 CCGEdge *e; 00736 int edgeSize = ccgSubSurf_getEdgeSize(ss); 00737 int x; 00738 short *edgeFlag; 00739 unsigned int flags = 0; 00740 00741 i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1); 00742 00743 e = ccgdm->edgeMap[i].edge; 00744 00745 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; 00746 00747 x = edgeNum - ccgdm->edgeMap[i].startEdge; 00748 00749 med->v1 = getEdgeIndex(ss, e, x, edgeSize); 00750 med->v2 = getEdgeIndex(ss, e, x+1, edgeSize); 00751 00752 edgeFlag = (ccgdm->edgeFlags)? &ccgdm->edgeFlags[i]: NULL; 00753 if(edgeFlag) 00754 flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) 00755 | ME_EDGEDRAW | ME_EDGERENDER; 00756 else 00757 flags |= ME_EDGEDRAW | ME_EDGERENDER; 00758 00759 med->flag = flags; 00760 } 00761 } 00762 00763 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) 00764 { 00765 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00766 CCGSubSurf *ss = ccgdm->ss; 00767 int gridSize = ccgSubSurf_getGridSize(ss); 00768 int edgeSize = ccgSubSurf_getEdgeSize(ss); 00769 int gridSideEdges = gridSize - 1; 00770 int gridFaces = gridSideEdges * gridSideEdges; 00771 int i; 00772 CCGFace *f; 00773 /*int numVerts;*/ 00774 int offset; 00775 int grid; 00776 int x, y; 00777 int lastface = ccgSubSurf_getNumFaces(ss) - 1; 00778 char *faceFlags = ccgdm->faceFlags; 00779 00780 memset(mf, 0, sizeof(*mf)); 00781 00782 i = 0; 00783 while(i < lastface && faceNum >= ccgdm->faceMap[i + 1].startFace) 00784 ++i; 00785 00786 f = ccgdm->faceMap[i].face; 00787 /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/ 00788 00789 offset = faceNum - ccgdm->faceMap[i].startFace; 00790 grid = offset / gridFaces; 00791 offset %= gridFaces; 00792 y = offset / gridSideEdges; 00793 x = offset % gridSideEdges; 00794 00795 mf->v1 = getFaceIndex(ss, f, grid, x+0, y+0, edgeSize, gridSize); 00796 mf->v2 = getFaceIndex(ss, f, grid, x+0, y+1, edgeSize, gridSize); 00797 mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize); 00798 mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize); 00799 00800 if(faceFlags) { 00801 mf->flag = faceFlags[i*2]; 00802 mf->mat_nr = faceFlags[i*2+1]; 00803 } 00804 else mf->flag = ME_SMOOTH; 00805 } 00806 00807 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) 00808 { 00809 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00810 CCGSubSurf *ss = ccgdm->ss; 00811 DMGridData *vd; 00812 int index; 00813 int totvert, totedge, totface; 00814 int gridSize = ccgSubSurf_getGridSize(ss); 00815 int edgeSize = ccgSubSurf_getEdgeSize(ss); 00816 int i = 0; 00817 00818 totface = ccgSubSurf_getNumFaces(ss); 00819 for(index = 0; index < totface; index++) { 00820 CCGFace *f = ccgdm->faceMap[index].face; 00821 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); 00822 00823 vd= ccgSubSurf_getFaceCenterData(f); 00824 copy_v3_v3(mvert[i].co, vd->co); 00825 normal_float_to_short_v3(mvert[i].no, vd->no); 00826 i++; 00827 00828 for(S = 0; S < numVerts; S++) { 00829 for(x = 1; x < gridSize - 1; x++, i++) { 00830 vd= ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); 00831 copy_v3_v3(mvert[i].co, vd->co); 00832 normal_float_to_short_v3(mvert[i].no, vd->no); 00833 } 00834 } 00835 00836 for(S = 0; S < numVerts; S++) { 00837 for(y = 1; y < gridSize - 1; y++) { 00838 for(x = 1; x < gridSize - 1; x++, i++) { 00839 vd= ccgSubSurf_getFaceGridData(ss, f, S, x, y); 00840 copy_v3_v3(mvert[i].co, vd->co); 00841 normal_float_to_short_v3(mvert[i].no, vd->no); 00842 } 00843 } 00844 } 00845 } 00846 00847 totedge = ccgSubSurf_getNumEdges(ss); 00848 for(index = 0; index < totedge; index++) { 00849 CCGEdge *e = ccgdm->edgeMap[index].edge; 00850 int x; 00851 00852 for(x = 1; x < edgeSize - 1; x++, i++) { 00853 vd= ccgSubSurf_getEdgeData(ss, e, x); 00854 copy_v3_v3(mvert[i].co, vd->co); 00855 /* This gives errors with -debug-fpe 00856 * the normals dont seem to be unit length. 00857 * this is most likely caused by edges with no 00858 * faces which are now zerod out, see comment in: 00859 * ccgSubSurf__calcVertNormals(), - campbell */ 00860 normal_float_to_short_v3(mvert[i].no, vd->no); 00861 } 00862 } 00863 00864 totvert = ccgSubSurf_getNumVerts(ss); 00865 for(index = 0; index < totvert; index++) { 00866 CCGVert *v = ccgdm->vertMap[index].vert; 00867 00868 vd= ccgSubSurf_getVertData(ss, v); 00869 copy_v3_v3(mvert[i].co, vd->co); 00870 normal_float_to_short_v3(mvert[i].no, vd->no); 00871 i++; 00872 } 00873 } 00874 00875 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) 00876 { 00877 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00878 CCGSubSurf *ss = ccgdm->ss; 00879 int index; 00880 int totedge, totface; 00881 int gridSize = ccgSubSurf_getGridSize(ss); 00882 int edgeSize = ccgSubSurf_getEdgeSize(ss); 00883 int i = 0; 00884 short *edgeFlags = ccgdm->edgeFlags; 00885 00886 totface = ccgSubSurf_getNumFaces(ss); 00887 for(index = 0; index < totface; index++) { 00888 CCGFace *f = ccgdm->faceMap[index].face; 00889 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); 00890 00891 for(S = 0; S < numVerts; S++) { 00892 for(x = 0; x < gridSize - 1; x++) { 00893 MEdge *med = &medge[i]; 00894 00895 if(ccgdm->drawInteriorEdges) 00896 med->flag = ME_EDGEDRAW | ME_EDGERENDER; 00897 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize); 00898 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize); 00899 i++; 00900 } 00901 00902 for(x = 1; x < gridSize - 1; x++) { 00903 for(y = 0; y < gridSize - 1; y++) { 00904 MEdge *med; 00905 00906 med = &medge[i]; 00907 if(ccgdm->drawInteriorEdges) 00908 med->flag = ME_EDGEDRAW | ME_EDGERENDER; 00909 med->v1 = getFaceIndex(ss, f, S, x, y, 00910 edgeSize, gridSize); 00911 med->v2 = getFaceIndex(ss, f, S, x, y + 1, 00912 edgeSize, gridSize); 00913 i++; 00914 00915 med = &medge[i]; 00916 if(ccgdm->drawInteriorEdges) 00917 med->flag = ME_EDGEDRAW | ME_EDGERENDER; 00918 med->v1 = getFaceIndex(ss, f, S, y, x, 00919 edgeSize, gridSize); 00920 med->v2 = getFaceIndex(ss, f, S, y + 1, x, 00921 edgeSize, gridSize); 00922 i++; 00923 } 00924 } 00925 } 00926 } 00927 00928 totedge = ccgSubSurf_getNumEdges(ss); 00929 for(index = 0; index < totedge; index++) { 00930 CCGEdge *e = ccgdm->edgeMap[index].edge; 00931 unsigned int flags = 0; 00932 int x; 00933 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e)); 00934 00935 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; 00936 00937 if(edgeFlags) { 00938 if(edgeIdx != -1) { 00939 flags |= (edgeFlags[index] & (ME_SEAM | ME_SHARP)) 00940 | ME_EDGEDRAW | ME_EDGERENDER; 00941 } 00942 } else { 00943 flags |= ME_EDGEDRAW | ME_EDGERENDER; 00944 } 00945 00946 for(x = 0; x < edgeSize - 1; x++) { 00947 MEdge *med = &medge[i]; 00948 med->v1 = getEdgeIndex(ss, e, x, edgeSize); 00949 med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize); 00950 med->flag = flags; 00951 i++; 00952 } 00953 } 00954 } 00955 00956 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) 00957 { 00958 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00959 CCGSubSurf *ss = ccgdm->ss; 00960 int index; 00961 int totface; 00962 int gridSize = ccgSubSurf_getGridSize(ss); 00963 int edgeSize = ccgSubSurf_getEdgeSize(ss); 00964 int i = 0; 00965 char *faceFlags = ccgdm->faceFlags; 00966 00967 totface = ccgSubSurf_getNumFaces(ss); 00968 for(index = 0; index < totface; index++) { 00969 CCGFace *f = ccgdm->faceMap[index].face; 00970 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); 00971 int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; 00972 int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; 00973 00974 for(S = 0; S < numVerts; S++) { 00975 for(y = 0; y < gridSize - 1; y++) { 00976 for(x = 0; x < gridSize - 1; x++) { 00977 MFace *mf = &mface[i]; 00978 mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0, 00979 edgeSize, gridSize); 00980 mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1, 00981 edgeSize, gridSize); 00982 mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1, 00983 edgeSize, gridSize); 00984 mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0, 00985 edgeSize, gridSize); 00986 mf->mat_nr = mat_nr; 00987 mf->flag = flag; 00988 00989 i++; 00990 } 00991 } 00992 } 00993 } 00994 } 00995 00996 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) { 00997 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 00998 CCGSubSurf *ss = ccgdm->ss; 00999 int edgeSize = ccgSubSurf_getEdgeSize(ss); 01000 int gridSize = ccgSubSurf_getGridSize(ss); 01001 int i; 01002 CCGVertIterator *vi; 01003 CCGEdgeIterator *ei; 01004 CCGFaceIterator *fi; 01005 CCGFace **faceMap2; 01006 CCGEdge **edgeMap2; 01007 CCGVert **vertMap2; 01008 int index, totvert, totedge, totface; 01009 01010 totvert = ccgSubSurf_getNumVerts(ss); 01011 vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap"); 01012 vi = ccgSubSurf_getVertIterator(ss); 01013 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { 01014 CCGVert *v = ccgVertIterator_getCurrent(vi); 01015 01016 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v; 01017 } 01018 ccgVertIterator_free(vi); 01019 01020 totedge = ccgSubSurf_getNumEdges(ss); 01021 edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap"); 01022 ei = ccgSubSurf_getEdgeIterator(ss); 01023 for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) { 01024 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); 01025 01026 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e; 01027 } 01028 01029 totface = ccgSubSurf_getNumFaces(ss); 01030 faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap"); 01031 fi = ccgSubSurf_getFaceIterator(ss); 01032 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { 01033 CCGFace *f = ccgFaceIterator_getCurrent(fi); 01034 01035 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f; 01036 } 01037 ccgFaceIterator_free(fi); 01038 01039 i = 0; 01040 for (index=0; index<totface; index++) { 01041 CCGFace *f = faceMap2[index]; 01042 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); 01043 01044 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f)); 01045 01046 for (S=0; S<numVerts; S++) { 01047 for (x=1; x<gridSize-1; x++) { 01048 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); 01049 } 01050 } 01051 01052 for (S=0; S<numVerts; S++) { 01053 for (y=1; y<gridSize-1; y++) { 01054 for (x=1; x<gridSize-1; x++) { 01055 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y)); 01056 } 01057 } 01058 } 01059 } 01060 01061 for (index=0; index<totedge; index++) { 01062 CCGEdge *e= edgeMap2[index]; 01063 int x; 01064 01065 for (x=1; x<edgeSize-1; x++) { 01066 copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x)); 01067 } 01068 } 01069 01070 for (index=0; index<totvert; index++) { 01071 CCGVert *v = vertMap2[index]; 01072 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v)); 01073 } 01074 01075 MEM_freeN(vertMap2); 01076 MEM_freeN(edgeMap2); 01077 MEM_freeN(faceMap2); 01078 } 01079 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) { 01080 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01081 CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss); 01082 01083 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { 01084 CCGVert *v = ccgVertIterator_getCurrent(vi); 01085 DMGridData *vd = ccgSubSurf_getVertData(ccgdm->ss, v); 01086 int index = ccgDM_getVertMapIndex(ccgdm->ss, v); 01087 01088 if (index!=-1) 01089 func(userData, index, vd->co, vd->no, NULL); 01090 } 01091 01092 ccgVertIterator_free(vi); 01093 } 01094 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) { 01095 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01096 CCGSubSurf *ss = ccgdm->ss; 01097 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); 01098 int i, edgeSize = ccgSubSurf_getEdgeSize(ss); 01099 01100 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { 01101 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); 01102 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); 01103 int index = ccgDM_getEdgeMapIndex(ss, e); 01104 01105 if (index!=-1) { 01106 for (i=0; i<edgeSize-1; i++) 01107 func(userData, index, edgeData[i].co, edgeData[i+1].co); 01108 } 01109 } 01110 01111 ccgEdgeIterator_free(ei); 01112 } 01113 01114 static void ccgDM_drawVerts(DerivedMesh *dm) { 01115 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01116 CCGSubSurf *ss = ccgdm->ss; 01117 int edgeSize = ccgSubSurf_getEdgeSize(ss); 01118 int gridSize = ccgSubSurf_getGridSize(ss); 01119 CCGVertIterator *vi; 01120 CCGEdgeIterator *ei; 01121 CCGFaceIterator *fi; 01122 01123 glBegin(GL_POINTS); 01124 vi = ccgSubSurf_getVertIterator(ss); 01125 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { 01126 CCGVert *v = ccgVertIterator_getCurrent(vi); 01127 glVertex3fv(ccgSubSurf_getVertData(ss, v)); 01128 } 01129 ccgVertIterator_free(vi); 01130 01131 ei = ccgSubSurf_getEdgeIterator(ss); 01132 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { 01133 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); 01134 int x; 01135 01136 for (x=1; x<edgeSize-1; x++) 01137 glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x)); 01138 } 01139 ccgEdgeIterator_free(ei); 01140 01141 fi = ccgSubSurf_getFaceIterator(ss); 01142 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { 01143 CCGFace *f = ccgFaceIterator_getCurrent(fi); 01144 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); 01145 01146 glVertex3fv(ccgSubSurf_getFaceCenterData(f)); 01147 for (S=0; S<numVerts; S++) 01148 for (x=1; x<gridSize-1; x++) 01149 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); 01150 for (S=0; S<numVerts; S++) 01151 for (y=1; y<gridSize-1; y++) 01152 for (x=1; x<gridSize-1; x++) 01153 glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y)); 01154 } 01155 ccgFaceIterator_free(fi); 01156 glEnd(); 01157 } 01158 01159 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm) 01160 { 01161 if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) { 01162 CCGFace **faces; 01163 int totface; 01164 01165 BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void***)&faces, &totface); 01166 if(totface) { 01167 ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface); 01168 ccgSubSurf_updateNormals(ccgdm->ss, faces, totface); 01169 MEM_freeN(faces); 01170 } 01171 } 01172 } 01173 01174 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(drawAllEdges)) { 01175 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01176 CCGSubSurf *ss = ccgdm->ss; 01177 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); 01178 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); 01179 int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss); 01180 int totedge = ccgSubSurf_getNumEdges(ss); 01181 int gridSize = ccgSubSurf_getGridSize(ss); 01182 int useAging; 01183 01184 ccgdm_pbvh_update(ccgdm); 01185 01186 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); 01187 01188 for (j=0; j< totedge; j++) { 01189 CCGEdge *e = ccgdm->edgeMap[j].edge; 01190 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); 01191 01192 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e)) 01193 continue; 01194 01195 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW)) 01196 continue; 01197 01198 if (useAging && !(G.f&G_BACKBUFSEL)) { 01199 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4; 01200 glColor3ub(0, ageCol>0?ageCol:0, 0); 01201 } 01202 01203 glBegin(GL_LINE_STRIP); 01204 for (i=0; i<edgeSize-1; i++) { 01205 glVertex3fv(edgeData[i].co); 01206 glVertex3fv(edgeData[i+1].co); 01207 } 01208 glEnd(); 01209 } 01210 01211 if (useAging && !(G.f&G_BACKBUFSEL)) { 01212 glColor3ub(0, 0, 0); 01213 } 01214 01215 if (ccgdm->drawInteriorEdges) { 01216 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { 01217 CCGFace *f = ccgFaceIterator_getCurrent(fi); 01218 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); 01219 01220 for (S=0; S<numVerts; S++) { 01221 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); 01222 01223 glBegin(GL_LINE_STRIP); 01224 for (x=0; x<gridSize; x++) 01225 glVertex3fv(faceGridData[x].co); 01226 glEnd(); 01227 for (y=1; y<gridSize-1; y++) { 01228 glBegin(GL_LINE_STRIP); 01229 for (x=0; x<gridSize; x++) 01230 glVertex3fv(faceGridData[y*gridSize + x].co); 01231 glEnd(); 01232 } 01233 for (x=1; x<gridSize-1; x++) { 01234 glBegin(GL_LINE_STRIP); 01235 for (y=0; y<gridSize; y++) 01236 glVertex3fv(faceGridData[y*gridSize + x].co); 01237 glEnd(); 01238 } 01239 } 01240 } 01241 } 01242 01243 ccgFaceIterator_free(fi); 01244 ccgEdgeIterator_free(ei); 01245 } 01246 static void ccgDM_drawLooseEdges(DerivedMesh *dm) { 01247 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01248 CCGSubSurf *ss = ccgdm->ss; 01249 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); 01250 int i, edgeSize = ccgSubSurf_getEdgeSize(ss); 01251 01252 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { 01253 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); 01254 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); 01255 01256 if (!ccgSubSurf_getEdgeNumFaces(e)) { 01257 glBegin(GL_LINE_STRIP); 01258 for (i=0; i<edgeSize-1; i++) { 01259 glVertex3fv(edgeData[i].co); 01260 glVertex3fv(edgeData[i+1].co); 01261 } 01262 glEnd(); 01263 } 01264 } 01265 01266 ccgEdgeIterator_free(ei); 01267 } 01268 01269 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d) 01270 { 01271 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2]; 01272 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2]; 01273 float no[3]; 01274 01275 no[0] = b_dY*a_cZ - b_dZ*a_cY; 01276 no[1] = b_dZ*a_cX - b_dX*a_cZ; 01277 no[2] = b_dX*a_cY - b_dY*a_cX; 01278 01279 /* don't normalize, GL_NORMALIZE is enabled */ 01280 glNormal3fv(no); 01281 } 01282 01283 /* Only used by non-editmesh types */ 01284 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) { 01285 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01286 CCGSubSurf *ss = ccgdm->ss; 01287 CCGFaceIterator *fi; 01288 int gridSize = ccgSubSurf_getGridSize(ss); 01289 char *faceFlags = ccgdm->faceFlags; 01290 int step = (fast)? gridSize-1: 1; 01291 01292 ccgdm_pbvh_update(ccgdm); 01293 01294 if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) { 01295 if(dm->numFaceData) { 01296 /* should be per face */ 01297 if(!setMaterial(faceFlags[1]+1, NULL)) 01298 return; 01299 01300 glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT); 01301 BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH)); 01302 glShadeModel(GL_FLAT); 01303 } 01304 01305 return; 01306 } 01307 01308 fi = ccgSubSurf_getFaceIterator(ss); 01309 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { 01310 CCGFace *f = ccgFaceIterator_getCurrent(fi); 01311 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); 01312 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); 01313 int drawSmooth, mat_nr; 01314 01315 if(faceFlags) { 01316 drawSmooth = (faceFlags[index*2] & ME_SMOOTH); 01317 mat_nr= faceFlags[index*2 + 1]; 01318 } 01319 else { 01320 drawSmooth = 1; 01321 mat_nr= 0; 01322 } 01323 01324 if (!setMaterial(mat_nr+1, NULL)) 01325 continue; 01326 01327 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT); 01328 for (S=0; S<numVerts; S++) { 01329 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); 01330 01331 if (drawSmooth) { 01332 for (y=0; y<gridSize-1; y+=step) { 01333 glBegin(GL_QUAD_STRIP); 01334 for (x=0; x<gridSize; x+=step) { 01335 DMGridData *a = &faceGridData[(y+0)*gridSize + x]; 01336 DMGridData *b = &faceGridData[(y+step)*gridSize + x]; 01337 01338 glNormal3fv(a->no); 01339 glVertex3fv(a->co); 01340 glNormal3fv(b->no); 01341 glVertex3fv(b->co); 01342 } 01343 glEnd(); 01344 } 01345 } else { 01346 glBegin(GL_QUADS); 01347 for (y=0; y<gridSize-1; y+=step) { 01348 for (x=0; x<gridSize-1; x+=step) { 01349 float *a = faceGridData[(y+0)*gridSize + x].co; 01350 float *b = faceGridData[(y+0)*gridSize + x + step].co; 01351 float *c = faceGridData[(y+step)*gridSize + x + step].co; 01352 float *d = faceGridData[(y+step)*gridSize + x].co; 01353 01354 ccgDM_glNormalFast(a, b, c, d); 01355 01356 glVertex3fv(d); 01357 glVertex3fv(c); 01358 glVertex3fv(b); 01359 glVertex3fv(a); 01360 } 01361 } 01362 glEnd(); 01363 } 01364 } 01365 } 01366 01367 ccgFaceIterator_free(fi); 01368 } 01369 01370 /* Only used by non-editmesh types */ 01371 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) { 01372 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01373 CCGSubSurf *ss = ccgdm->ss; 01374 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); 01375 GPUVertexAttribs gattribs; 01376 DMVertexAttribs attribs= {{{NULL}}}; 01377 MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); 01378 int gridSize = ccgSubSurf_getGridSize(ss); 01379 int gridFaces = gridSize - 1; 01380 int edgeSize = ccgSubSurf_getEdgeSize(ss); 01381 int transp, orig_transp, new_transp; 01382 char *faceFlags = ccgdm->faceFlags; 01383 int a, b, i, doDraw, numVerts, matnr, new_matnr, totface; 01384 01385 ccgdm_pbvh_update(ccgdm); 01386 01387 doDraw = 0; 01388 matnr = -1; 01389 transp = GPU_get_material_blend_mode(); 01390 orig_transp = transp; 01391 01392 #define PASSATTRIB(dx, dy, vert) { \ 01393 if(attribs.totorco) { \ 01394 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize); \ 01395 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \ 01396 } \ 01397 for(b = 0; b < attribs.tottface; b++) { \ 01398 MTFace *tf = &attribs.tface[b].array[a]; \ 01399 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \ 01400 } \ 01401 for(b = 0; b < attribs.totmcol; b++) { \ 01402 MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \ 01403 GLubyte col[4]; \ 01404 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \ 01405 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \ 01406 } \ 01407 if(attribs.tottang) { \ 01408 float *tang = attribs.tang.array[a*4 + vert]; \ 01409 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \ 01410 } \ 01411 } 01412 01413 totface = ccgSubSurf_getNumFaces(ss); 01414 for(a = 0, i = 0; i < totface; i++) { 01415 CCGFace *f = ccgdm->faceMap[i].face; 01416 int S, x, y, drawSmooth; 01417 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); 01418 int origIndex = ccgDM_getFaceMapIndex(ss, f); 01419 01420 numVerts = ccgSubSurf_getFaceNumVerts(f); 01421 01422 if(faceFlags) { 01423 drawSmooth = (faceFlags[index*2] & ME_SMOOTH); 01424 new_matnr= faceFlags[index*2 + 1] + 1; 01425 } 01426 else { 01427 drawSmooth = 1; 01428 new_matnr= 1; 01429 } 01430 01431 if(new_matnr != matnr) { 01432 doDraw = setMaterial(matnr = new_matnr, &gattribs); 01433 if(doDraw) 01434 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); 01435 } 01436 01437 if(!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && !setDrawOptions(userData, origIndex))) { 01438 a += gridFaces*gridFaces*numVerts; 01439 continue; 01440 } 01441 01442 if(tf) { 01443 new_transp = tf[i].transp; 01444 01445 if(new_transp != transp) { 01446 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID) 01447 GPU_set_material_blend_mode(orig_transp); 01448 else 01449 GPU_set_material_blend_mode(new_transp); 01450 transp = new_transp; 01451 } 01452 } 01453 01454 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT); 01455 for (S=0; S<numVerts; S++) { 01456 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); 01457 DMGridData *vda, *vdb; 01458 01459 if (drawSmooth) { 01460 for (y=0; y<gridFaces; y++) { 01461 glBegin(GL_QUAD_STRIP); 01462 for (x=0; x<gridFaces; x++) { 01463 vda = &faceGridData[(y+0)*gridSize + x]; 01464 vdb = &faceGridData[(y+1)*gridSize + x]; 01465 01466 PASSATTRIB(0, 0, 0); 01467 glNormal3fv(vda->no); 01468 glVertex3fv(vda->co); 01469 01470 PASSATTRIB(0, 1, 1); 01471 glNormal3fv(vdb->no); 01472 glVertex3fv(vdb->co); 01473 01474 if(x != gridFaces-1) 01475 a++; 01476 } 01477 01478 vda = &faceGridData[(y+0)*gridSize + x]; 01479 vdb = &faceGridData[(y+1)*gridSize + x]; 01480 01481 PASSATTRIB(0, 0, 3); 01482 glNormal3fv(vda->no); 01483 glVertex3fv(vda->co); 01484 01485 PASSATTRIB(0, 1, 2); 01486 glNormal3fv(vdb->no); 01487 glVertex3fv(vdb->co); 01488 01489 glEnd(); 01490 01491 a++; 01492 } 01493 } else { 01494 glBegin(GL_QUADS); 01495 for (y=0; y<gridFaces; y++) { 01496 for (x=0; x<gridFaces; x++) { 01497 float *aco = faceGridData[(y+0)*gridSize + x].co; 01498 float *bco = faceGridData[(y+0)*gridSize + x + 1].co; 01499 float *cco = faceGridData[(y+1)*gridSize + x + 1].co; 01500 float *dco = faceGridData[(y+1)*gridSize + x].co; 01501 01502 ccgDM_glNormalFast(aco, bco, cco, dco); 01503 01504 PASSATTRIB(0, 1, 1); 01505 glVertex3fv(dco); 01506 PASSATTRIB(1, 1, 2); 01507 glVertex3fv(cco); 01508 PASSATTRIB(1, 0, 3); 01509 glVertex3fv(bco); 01510 PASSATTRIB(0, 0, 0); 01511 glVertex3fv(aco); 01512 01513 a++; 01514 } 01515 } 01516 glEnd(); 01517 } 01518 } 01519 } 01520 01521 #undef PASSATTRIB 01522 01523 ccgFaceIterator_free(fi); 01524 } 01525 01526 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) { 01527 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); 01528 } 01529 01530 static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) { 01531 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01532 CCGSubSurf *ss = ccgdm->ss; 01533 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); 01534 int gridSize = ccgSubSurf_getGridSize(ss); 01535 unsigned char *cp1, *cp2; 01536 int useTwoSide=1; 01537 01538 ccgdm_pbvh_update(ccgdm); 01539 01540 cp1= col1; 01541 if(col2) { 01542 cp2= col2; 01543 } else { 01544 cp2= NULL; 01545 useTwoSide= 0; 01546 } 01547 01548 glShadeModel(GL_SMOOTH); 01549 01550 if(col2) { 01551 glEnable(GL_CULL_FACE); 01552 } 01553 01554 glBegin(GL_QUADS); 01555 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { 01556 CCGFace *f = ccgFaceIterator_getCurrent(fi); 01557 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); 01558 01559 for (S=0; S<numVerts; S++) { 01560 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); 01561 for (y=0; y<gridSize-1; y++) { 01562 for (x=0; x<gridSize-1; x++) { 01563 float *a = faceGridData[(y+0)*gridSize + x].co; 01564 float *b = faceGridData[(y+0)*gridSize + x + 1].co; 01565 float *c = faceGridData[(y+1)*gridSize + x + 1].co; 01566 float *d = faceGridData[(y+1)*gridSize + x].co; 01567 01568 glColor3ub(cp1[3], cp1[2], cp1[1]); 01569 glVertex3fv(d); 01570 glColor3ub(cp1[7], cp1[6], cp1[5]); 01571 glVertex3fv(c); 01572 glColor3ub(cp1[11], cp1[10], cp1[9]); 01573 glVertex3fv(b); 01574 glColor3ub(cp1[15], cp1[14], cp1[13]); 01575 glVertex3fv(a); 01576 01577 if (useTwoSide) { 01578 glColor3ub(cp2[15], cp2[14], cp2[13]); 01579 glVertex3fv(a); 01580 glColor3ub(cp2[11], cp2[10], cp2[9]); 01581 glVertex3fv(b); 01582 glColor3ub(cp2[7], cp2[6], cp2[5]); 01583 glVertex3fv(c); 01584 glColor3ub(cp2[3], cp2[2], cp2[1]); 01585 glVertex3fv(d); 01586 } 01587 01588 if (cp2) cp2+=16; 01589 cp1+=16; 01590 } 01591 } 01592 } 01593 } 01594 glEnd(); 01595 01596 ccgFaceIterator_free(fi); 01597 } 01598 01599 static void ccgDM_drawFacesTex_common(DerivedMesh *dm, 01600 int (*drawParams)(MTFace *tface, MCol *mcol, int matnr), 01601 int (*drawParamsMapped)(void *userData, int index), 01602 void *userData) 01603 { 01604 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01605 CCGSubSurf *ss = ccgdm->ss; 01606 MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); 01607 MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE); 01608 char *faceFlags = ccgdm->faceFlags; 01609 int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss); 01610 int gridFaces = gridSize - 1; 01611 01612 ccgdm_pbvh_update(ccgdm); 01613 01614 if(!mcol) 01615 mcol = dm->getFaceDataArray(dm, CD_MCOL); 01616 01617 totface = ccgSubSurf_getNumFaces(ss); 01618 for(i = 0; i < totface; i++) { 01619 CCGFace *f = ccgdm->faceMap[i].face; 01620 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); 01621 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); 01622 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); 01623 unsigned char *cp= NULL; 01624 int mat_nr; 01625 01626 if(faceFlags) { 01627 drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH); 01628 mat_nr= faceFlags[origIndex*2 + 1]; 01629 } 01630 else { 01631 drawSmooth = 1; 01632 mat_nr= 0; 01633 } 01634 01635 if(drawParams) 01636 flag = drawParams(tf, mcol, mat_nr); 01637 else if (index != ORIGINDEX_NONE) 01638 flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1; 01639 else 01640 flag= GPU_enable_material(mat_nr, NULL) ? 1:0; 01641 01642 01643 if (flag == 0) { /* flag 0 == the face is hidden or invisible */ 01644 if(tf) tf += gridFaces*gridFaces*numVerts; 01645 if(mcol) mcol += gridFaces*gridFaces*numVerts*4; 01646 continue; 01647 } 01648 01649 /* flag 1 == use vertex colors */ 01650 if(mcol) { 01651 if(flag==1) cp= (unsigned char*)mcol; 01652 mcol += gridFaces*gridFaces*numVerts*4; 01653 } 01654 01655 for (S=0; S<numVerts; S++) { 01656 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); 01657 DMGridData *a, *b; 01658 01659 if (drawSmooth) { 01660 glShadeModel(GL_SMOOTH); 01661 for (y=0; y<gridFaces; y++) { 01662 glBegin(GL_QUAD_STRIP); 01663 for (x=0; x<gridFaces; x++) { 01664 a = &faceGridData[(y+0)*gridSize + x]; 01665 b = &faceGridData[(y+1)*gridSize + x]; 01666 01667 if(tf) glTexCoord2fv(tf->uv[0]); 01668 if(cp) glColor3ub(cp[3], cp[2], cp[1]); 01669 glNormal3fv(a->no); 01670 glVertex3fv(a->co); 01671 01672 if(tf) glTexCoord2fv(tf->uv[1]); 01673 if(cp) glColor3ub(cp[7], cp[6], cp[5]); 01674 glNormal3fv(b->no); 01675 glVertex3fv(b->co); 01676 01677 if(x != gridFaces-1) { 01678 if(tf) tf++; 01679 if(cp) cp += 16; 01680 } 01681 } 01682 01683 a = &faceGridData[(y+0)*gridSize + x]; 01684 b = &faceGridData[(y+1)*gridSize + x]; 01685 01686 if(tf) glTexCoord2fv(tf->uv[3]); 01687 if(cp) glColor3ub(cp[15], cp[14], cp[13]); 01688 glNormal3fv(a->no); 01689 glVertex3fv(a->co); 01690 01691 if(tf) glTexCoord2fv(tf->uv[2]); 01692 if(cp) glColor3ub(cp[11], cp[10], cp[9]); 01693 glNormal3fv(b->no); 01694 glVertex3fv(b->co); 01695 01696 if(tf) tf++; 01697 if(cp) cp += 16; 01698 01699 glEnd(); 01700 } 01701 } else { 01702 glShadeModel(GL_FLAT); 01703 glBegin(GL_QUADS); 01704 for (y=0; y<gridFaces; y++) { 01705 for (x=0; x<gridFaces; x++) { 01706 float *a_co = faceGridData[(y+0)*gridSize + x].co; 01707 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co; 01708 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co; 01709 float *d_co = faceGridData[(y+1)*gridSize + x].co; 01710 01711 ccgDM_glNormalFast(a_co, b_co, c_co, d_co); 01712 01713 if(tf) glTexCoord2fv(tf->uv[1]); 01714 if(cp) glColor3ub(cp[7], cp[6], cp[5]); 01715 glVertex3fv(d_co); 01716 01717 if(tf) glTexCoord2fv(tf->uv[2]); 01718 if(cp) glColor3ub(cp[11], cp[10], cp[9]); 01719 glVertex3fv(c_co); 01720 01721 if(tf) glTexCoord2fv(tf->uv[3]); 01722 if(cp) glColor3ub(cp[15], cp[14], cp[13]); 01723 glVertex3fv(b_co); 01724 01725 if(tf) glTexCoord2fv(tf->uv[0]); 01726 if(cp) glColor3ub(cp[3], cp[2], cp[1]); 01727 glVertex3fv(a_co); 01728 01729 if(tf) tf++; 01730 if(cp) cp += 16; 01731 } 01732 } 01733 glEnd(); 01734 } 01735 } 01736 } 01737 } 01738 01739 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr)) 01740 { 01741 ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL); 01742 } 01743 01744 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 01745 { 01746 ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData); 01747 } 01748 01749 static void ccgDM_drawUVEdges(DerivedMesh *dm) 01750 { 01751 01752 MFace *mf = dm->getFaceArray(dm); 01753 MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE); 01754 int i; 01755 01756 if (tf) { 01757 glBegin(GL_LINES); 01758 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) { 01759 if(!(mf->flag&ME_HIDE)) { 01760 glVertex2fv(tf->uv[0]); 01761 glVertex2fv(tf->uv[1]); 01762 01763 glVertex2fv(tf->uv[1]); 01764 glVertex2fv(tf->uv[2]); 01765 01766 if(!mf->v4) { 01767 glVertex2fv(tf->uv[2]); 01768 glVertex2fv(tf->uv[0]); 01769 } else { 01770 glVertex2fv(tf->uv[2]); 01771 glVertex2fv(tf->uv[3]); 01772 01773 glVertex2fv(tf->uv[3]); 01774 glVertex2fv(tf->uv[0]); 01775 } 01776 } 01777 } 01778 glEnd(); 01779 } 01780 } 01781 01782 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs)) { 01783 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01784 CCGSubSurf *ss = ccgdm->ss; 01785 MCol *mcol= NULL; 01786 int i, gridSize = ccgSubSurf_getGridSize(ss); 01787 char *faceFlags = ccgdm->faceFlags; 01788 int gridFaces = gridSize - 1, totface; 01789 01790 if(useColors) { 01791 mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); 01792 if(!mcol) 01793 mcol = dm->getFaceDataArray(dm, CD_MCOL); 01794 } 01795 01796 totface = ccgSubSurf_getNumFaces(ss); 01797 for(i = 0; i < totface; i++) { 01798 CCGFace *f = ccgdm->faceMap[i].face; 01799 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); 01800 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); 01801 int origIndex; 01802 unsigned char *cp= NULL; 01803 01804 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); 01805 01806 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH); 01807 else drawSmooth = 1; 01808 01809 if(mcol) { 01810 cp= (unsigned char*)mcol; 01811 mcol += gridFaces*gridFaces*numVerts*4; 01812 } 01813 01814 { 01815 int draw= 1; 01816 01817 if(index == ORIGINDEX_NONE) 01818 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */ 01819 else if (setDrawOptions) 01820 draw= setDrawOptions(userData, index, &drawSmooth); 01821 01822 if (draw) { 01823 if (draw==2) { 01824 glEnable(GL_POLYGON_STIPPLE); 01825 glPolygonStipple(stipple_quarttone); 01826 } 01827 01828 for (S=0; S<numVerts; S++) { 01829 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); 01830 if (drawSmooth) { 01831 glShadeModel(GL_SMOOTH); 01832 for (y=0; y<gridFaces; y++) { 01833 DMGridData *a, *b; 01834 glBegin(GL_QUAD_STRIP); 01835 for (x=0; x<gridFaces; x++) { 01836 a = &faceGridData[(y+0)*gridSize + x]; 01837 b = &faceGridData[(y+1)*gridSize + x]; 01838 01839 if(cp) glColor3ub(cp[3], cp[2], cp[1]); 01840 glNormal3fv(a->no); 01841 glVertex3fv(a->co); 01842 if(cp) glColor3ub(cp[7], cp[6], cp[5]); 01843 glNormal3fv(b->no); 01844 glVertex3fv(b->co); 01845 01846 if(x != gridFaces-1) { 01847 if(cp) cp += 16; 01848 } 01849 } 01850 01851 a = &faceGridData[(y+0)*gridSize + x]; 01852 b = &faceGridData[(y+1)*gridSize + x]; 01853 01854 if(cp) glColor3ub(cp[15], cp[14], cp[13]); 01855 glNormal3fv(a->no); 01856 glVertex3fv(a->co); 01857 if(cp) glColor3ub(cp[11], cp[10], cp[9]); 01858 glNormal3fv(b->no); 01859 glVertex3fv(b->co); 01860 01861 if(cp) cp += 16; 01862 01863 glEnd(); 01864 } 01865 } else { 01866 glShadeModel(GL_FLAT); 01867 glBegin(GL_QUADS); 01868 for (y=0; y<gridFaces; y++) { 01869 for (x=0; x<gridFaces; x++) { 01870 float *a = faceGridData[(y+0)*gridSize + x].co; 01871 float *b = faceGridData[(y+0)*gridSize + x + 1].co; 01872 float *c = faceGridData[(y+1)*gridSize + x + 1].co; 01873 float *d = faceGridData[(y+1)*gridSize + x].co; 01874 01875 ccgDM_glNormalFast(a, b, c, d); 01876 01877 if(cp) glColor3ub(cp[7], cp[6], cp[5]); 01878 glVertex3fv(d); 01879 if(cp) glColor3ub(cp[11], cp[10], cp[9]); 01880 glVertex3fv(c); 01881 if(cp) glColor3ub(cp[15], cp[14], cp[13]); 01882 glVertex3fv(b); 01883 if(cp) glColor3ub(cp[3], cp[2], cp[1]); 01884 glVertex3fv(a); 01885 01886 if(cp) cp += 16; 01887 } 01888 } 01889 glEnd(); 01890 } 01891 } 01892 if (draw==2) 01893 glDisable(GL_POLYGON_STIPPLE); 01894 } 01895 } 01896 } 01897 } 01898 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) { 01899 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01900 CCGSubSurf *ss = ccgdm->ss; 01901 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); 01902 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); 01903 01904 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); 01905 01906 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { 01907 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); 01908 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); 01909 int index = ccgDM_getEdgeMapIndex(ss, e); 01910 01911 glBegin(GL_LINE_STRIP); 01912 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) { 01913 if (useAging && !(G.f&G_BACKBUFSEL)) { 01914 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4; 01915 glColor3ub(0, ageCol>0?ageCol:0, 0); 01916 } 01917 01918 for (i=0; i<edgeSize-1; i++) { 01919 glVertex3fv(edgeData[i].co); 01920 glVertex3fv(edgeData[i+1].co); 01921 } 01922 } 01923 glEnd(); 01924 } 01925 01926 ccgEdgeIterator_free(ei); 01927 } 01928 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) { 01929 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01930 CCGSubSurf *ss = ccgdm->ss; 01931 CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); 01932 int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); 01933 01934 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); 01935 01936 for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { 01937 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); 01938 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); 01939 int index = ccgDM_getEdgeMapIndex(ss, e); 01940 01941 glBegin(GL_LINE_STRIP); 01942 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) { 01943 for (i=0; i<edgeSize; i++) { 01944 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1)); 01945 01946 if (useAging && !(G.f&G_BACKBUFSEL)) { 01947 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4; 01948 glColor3ub(0, ageCol>0?ageCol:0, 0); 01949 } 01950 01951 glVertex3fv(edgeData[i].co); 01952 } 01953 } 01954 glEnd(); 01955 } 01956 01957 ccgEdgeIterator_free(ei); 01958 } 01959 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) { 01960 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01961 CCGSubSurf *ss = ccgdm->ss; 01962 CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); 01963 01964 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { 01965 CCGFace *f = ccgFaceIterator_getCurrent(fi); 01966 int index = ccgDM_getFaceMapIndex(ss, f); 01967 01968 if (index!=-1) { 01969 /* Face center data normal isn't updated atm. */ 01970 DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0); 01971 01972 func(userData, index, vd->co, vd->no); 01973 } 01974 } 01975 01976 ccgFaceIterator_free(fi); 01977 } 01978 01979 static void ccgDM_release(DerivedMesh *dm) { 01980 CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; 01981 01982 if (DM_release(dm)) { 01983 /* Before freeing, need to update the displacement map */ 01984 if(ccgdm->multires.modified) { 01985 /* Check that mmd still exists */ 01986 if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0) 01987 ccgdm->multires.mmd = NULL; 01988 if(ccgdm->multires.mmd) 01989 ccgdm->multires.update(dm); 01990 } 01991 01992 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces); 01993 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData); 01994 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency); 01995 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset); 01996 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss); 01997 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap); 01998 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem); 01999 MEM_freeN(ccgdm->edgeFlags); 02000 MEM_freeN(ccgdm->faceFlags); 02001 MEM_freeN(ccgdm->vertMap); 02002 MEM_freeN(ccgdm->edgeMap); 02003 MEM_freeN(ccgdm->faceMap); 02004 MEM_freeN(ccgdm); 02005 } 02006 } 02007 02008 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type) 02009 { 02010 if(type == CD_ORIGINDEX) { 02011 /* create origindex on demand to save memory */ 02012 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02013 CCGSubSurf *ss= ccgdm->ss; 02014 int *origindex; 02015 int a, index, totnone, totorig; 02016 02017 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); 02018 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX); 02019 02020 totorig = ccgSubSurf_getNumVerts(ss); 02021 totnone= dm->numVertData - totorig; 02022 02023 /* original vertices are at the end */ 02024 for(a=0; a<totnone; a++) 02025 origindex[a]= ORIGINDEX_NONE; 02026 02027 for(index=0; index<totorig; index++, a++) { 02028 CCGVert *v = ccgdm->vertMap[index].vert; 02029 origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v); 02030 } 02031 02032 return origindex; 02033 } 02034 02035 return DM_get_vert_data_layer(dm, type); 02036 } 02037 02038 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type) 02039 { 02040 if(type == CD_ORIGINDEX) { 02041 /* create origindex on demand to save memory */ 02042 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02043 CCGSubSurf *ss= ccgdm->ss; 02044 int *origindex; 02045 int a, i, index, totnone, totorig, totedge; 02046 int edgeSize= ccgSubSurf_getEdgeSize(ss); 02047 02048 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); 02049 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX); 02050 02051 totedge= ccgSubSurf_getNumEdges(ss); 02052 totorig= totedge*(edgeSize - 1); 02053 totnone= dm->numEdgeData - totorig; 02054 02055 /* original edges are at the end */ 02056 for(a=0; a<totnone; a++) 02057 origindex[a]= ORIGINDEX_NONE; 02058 02059 for(index=0; index<totedge; index++) { 02060 CCGEdge *e= ccgdm->edgeMap[index].edge; 02061 int mapIndex= ccgDM_getEdgeMapIndex(ss, e); 02062 02063 for(i = 0; i < edgeSize - 1; i++, a++) 02064 origindex[a]= mapIndex; 02065 } 02066 02067 return origindex; 02068 } 02069 02070 return DM_get_edge_data_layer(dm, type); 02071 } 02072 02073 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type) 02074 { 02075 if(type == CD_ORIGINDEX) { 02076 /* create origindex on demand to save memory */ 02077 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02078 CCGSubSurf *ss= ccgdm->ss; 02079 int *origindex; 02080 int a, i, index, totface; 02081 int gridFaces = ccgSubSurf_getGridSize(ss) - 1; 02082 02083 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); 02084 origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX); 02085 02086 totface= ccgSubSurf_getNumFaces(ss); 02087 02088 for(a=0, index=0; index<totface; index++) { 02089 CCGFace *f = ccgdm->faceMap[index].face; 02090 int numVerts = ccgSubSurf_getFaceNumVerts(f); 02091 int mapIndex = ccgDM_getFaceMapIndex(ss, f); 02092 02093 for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++) 02094 origindex[a]= mapIndex; 02095 } 02096 02097 return origindex; 02098 } 02099 02100 return DM_get_face_data_layer(dm, type); 02101 } 02102 02103 static int ccgDM_getNumGrids(DerivedMesh *dm) 02104 { 02105 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02106 int index, numFaces, numGrids; 02107 02108 numFaces= ccgSubSurf_getNumFaces(ccgdm->ss); 02109 numGrids= 0; 02110 02111 for(index=0; index<numFaces; index++) { 02112 CCGFace *f = ccgdm->faceMap[index].face; 02113 numGrids += ccgSubSurf_getFaceNumVerts(f); 02114 } 02115 02116 return numGrids; 02117 } 02118 02119 static int ccgDM_getGridSize(DerivedMesh *dm) 02120 { 02121 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02122 return ccgSubSurf_getGridSize(ccgdm->ss); 02123 } 02124 02125 static int ccgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset) 02126 { 02127 CCGFace *adjf; 02128 CCGEdge *e; 02129 int i, j= 0, numFaces, fIndex, numEdges= 0; 02130 02131 e = ccgSubSurf_getFaceEdge(ss, f, S); 02132 numFaces = ccgSubSurf_getEdgeNumFaces(e); 02133 02134 if(numFaces != 2) 02135 return -1; 02136 02137 for(i = 0; i < numFaces; i++) { 02138 adjf = ccgSubSurf_getEdgeFace(e, i); 02139 02140 if(adjf != f) { 02141 numEdges = ccgSubSurf_getFaceNumVerts(adjf); 02142 for(j = 0; j < numEdges; j++) 02143 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e) 02144 break; 02145 02146 if(j != numEdges) 02147 break; 02148 } 02149 } 02150 02151 fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf)); 02152 02153 return gridOffset[fIndex] + (j + offset)%numEdges; 02154 } 02155 02156 static void ccgdm_create_grids(DerivedMesh *dm) 02157 { 02158 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02159 CCGSubSurf *ss= ccgdm->ss; 02160 DMGridData **gridData; 02161 DMGridAdjacency *gridAdjacency, *adj; 02162 CCGFace **gridFaces; 02163 int *gridOffset; 02164 int index, numFaces, numGrids, S, gIndex /*, gridSize*/; 02165 02166 if(ccgdm->gridData) 02167 return; 02168 02169 numGrids = ccgDM_getNumGrids(dm); 02170 numFaces = ccgSubSurf_getNumFaces(ss); 02171 /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/ 02172 02173 /* compute offset into grid array for each face */ 02174 gridOffset = MEM_mallocN(sizeof(int)*numFaces, "ccgdm.gridOffset"); 02175 02176 for(gIndex = 0, index = 0; index < numFaces; index++) { 02177 CCGFace *f = ccgdm->faceMap[index].face; 02178 int numVerts = ccgSubSurf_getFaceNumVerts(f); 02179 02180 gridOffset[index] = gIndex; 02181 gIndex += numVerts; 02182 } 02183 02184 /* compute grid data */ 02185 gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData"); 02186 gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency"); 02187 gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces"); 02188 02189 for(gIndex = 0, index = 0; index < numFaces; index++) { 02190 CCGFace *f = ccgdm->faceMap[index].face; 02191 int numVerts = ccgSubSurf_getFaceNumVerts(f); 02192 02193 for(S = 0; S < numVerts; S++, gIndex++) { 02194 int prevS = (S - 1 + numVerts) % numVerts; 02195 int nextS = (S + 1 + numVerts) % numVerts; 02196 02197 gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S); 02198 gridFaces[gIndex] = f; 02199 02200 adj = &gridAdjacency[gIndex]; 02201 02202 adj->index[0] = gIndex - S + nextS; 02203 adj->rotation[0] = 3; 02204 adj->index[1] = ccgdm_adjacent_grid(ss, gridOffset, f, prevS, 0); 02205 adj->rotation[1] = 1; 02206 adj->index[2] = ccgdm_adjacent_grid(ss, gridOffset, f, S, 1); 02207 adj->rotation[2] = 3; 02208 adj->index[3] = gIndex - S + prevS; 02209 adj->rotation[3] = 1; 02210 } 02211 } 02212 02213 ccgdm->gridData = gridData; 02214 ccgdm->gridFaces = gridFaces; 02215 ccgdm->gridAdjacency = gridAdjacency; 02216 ccgdm->gridOffset = gridOffset; 02217 } 02218 02219 static DMGridData **ccgDM_getGridData(DerivedMesh *dm) 02220 { 02221 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02222 02223 ccgdm_create_grids(dm); 02224 return ccgdm->gridData; 02225 } 02226 02227 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm) 02228 { 02229 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02230 02231 ccgdm_create_grids(dm); 02232 return ccgdm->gridAdjacency; 02233 } 02234 02235 static int *ccgDM_getGridOffset(DerivedMesh *dm) 02236 { 02237 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02238 02239 ccgdm_create_grids(dm); 02240 return ccgdm->gridOffset; 02241 } 02242 02243 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm) 02244 { 02245 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02246 02247 if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) { 02248 Mesh *me= ob->data; 02249 02250 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface, 02251 me->totvert, me->totface); 02252 } 02253 02254 return ccgdm->fmap; 02255 } 02256 02257 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm) 02258 { 02259 MultiresModifierData *mmd= ccgdm->multires.mmd; 02260 02261 /* both of multires and subsurm modifiers are CCG, but 02262 grids should only be used when sculpting on multires */ 02263 if(!mmd) 02264 return 0; 02265 02266 return 1; 02267 } 02268 02269 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) 02270 { 02271 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; 02272 int gridSize, numGrids, grid_pbvh; 02273 02274 if(!ob) { 02275 ccgdm->pbvh= NULL; 02276 return NULL; 02277 } 02278 02279 if(!ob->sculpt) 02280 return NULL; 02281 02282 grid_pbvh= ccgDM_use_grid_pbvh(ccgdm); 02283 02284 if(ob->sculpt->pbvh) { 02285 if(grid_pbvh) { 02286 /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm 02287 but this can be freed on ccgdm release, this updates the pointers 02288 when the ccgdm gets remade, the assumption is that the topology 02289 does not change. */ 02290 ccgdm_create_grids(dm); 02291 BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces); 02292 } 02293 02294 ccgdm->pbvh = ob->sculpt->pbvh; 02295 } 02296 02297 if(ccgdm->pbvh) 02298 return ccgdm->pbvh; 02299 02300 /* no pbvh exists yet, we need to create one. only in case of multires 02301 we build a pbvh over the modified mesh, in other cases the base mesh 02302 is being sculpted, so we build a pbvh from that. */ 02303 if(grid_pbvh) { 02304 ccgdm_create_grids(dm); 02305 02306 gridSize = ccgDM_getGridSize(dm); 02307 numGrids = ccgDM_getNumGrids(dm); 02308 02309 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); 02310 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, 02311 numGrids, gridSize, (void**)ccgdm->gridFaces); 02312 } else if(ob->type == OB_MESH) { 02313 Mesh *me= ob->data; 02314 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); 02315 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert, 02316 me->totface, me->totvert); 02317 } 02318 02319 return ccgdm->pbvh; 02320 } 02321 02322 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, 02323 int drawInteriorEdges, 02324 int useSubsurfUv, 02325 DerivedMesh *dm) 02326 { 02327 CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm"); 02328 CCGVertIterator *vi; 02329 CCGEdgeIterator *ei; 02330 CCGFaceIterator *fi; 02331 int index, totvert, totedge, totface; 02332 int i; 02333 int vertNum, edgeNum, faceNum; 02334 short *edgeFlags; 02335 char *faceFlags; 02336 int edgeSize; 02337 int gridSize; 02338 int gridFaces; 02339 /*int gridSideVerts;*/ 02340 int gridSideEdges; 02341 int gridInternalEdges; 02342 MEdge *medge = NULL; 02343 MFace *mface = NULL; 02344 int *orig_indices; 02345 FaceVertWeight *qweight, *tweight; 02346 02347 DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM, 02348 ccgSubSurf_getNumFinalVerts(ss), 02349 ccgSubSurf_getNumFinalEdges(ss), 02350 ccgSubSurf_getNumFinalFaces(ss)); 02351 02352 ccgdm->dm.getMinMax = ccgDM_getMinMax; 02353 ccgdm->dm.getNumVerts = ccgDM_getNumVerts; 02354 ccgdm->dm.getNumFaces = ccgDM_getNumFaces; 02355 02356 ccgdm->dm.getNumEdges = ccgDM_getNumEdges; 02357 ccgdm->dm.getVert = ccgDM_getFinalVert; 02358 ccgdm->dm.getEdge = ccgDM_getFinalEdge; 02359 ccgdm->dm.getFace = ccgDM_getFinalFace; 02360 ccgdm->dm.getVertCo = ccgDM_getFinalVertCo; 02361 ccgdm->dm.getVertNo = ccgDM_getFinalVertNo; 02362 ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray; 02363 ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray; 02364 ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray; 02365 ccgdm->dm.getVertData = DM_get_vert_data; 02366 ccgdm->dm.getEdgeData = DM_get_edge_data; 02367 ccgdm->dm.getFaceData = DM_get_face_data; 02368 ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer; 02369 ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer; 02370 ccgdm->dm.getFaceDataArray = ccgDM_get_face_data_layer; 02371 ccgdm->dm.getNumGrids = ccgDM_getNumGrids; 02372 ccgdm->dm.getGridSize = ccgDM_getGridSize; 02373 ccgdm->dm.getGridData = ccgDM_getGridData; 02374 ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency; 02375 ccgdm->dm.getGridOffset = ccgDM_getGridOffset; 02376 ccgdm->dm.getFaceMap = ccgDM_getFaceMap; 02377 ccgdm->dm.getPBVH = ccgDM_getPBVH; 02378 02379 ccgdm->dm.getVertCos = ccgdm_getVertCos; 02380 ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert; 02381 ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge; 02382 ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter; 02383 02384 ccgdm->dm.drawVerts = ccgDM_drawVerts; 02385 ccgdm->dm.drawEdges = ccgDM_drawEdges; 02386 ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges; 02387 ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid; 02388 ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored; 02389 ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex; 02390 ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL; 02391 ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces; 02392 ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex; 02393 ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL; 02394 ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges; 02395 02396 ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp; 02397 ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges; 02398 02399 ccgdm->dm.release = ccgDM_release; 02400 02401 ccgdm->ss = ss; 02402 ccgdm->drawInteriorEdges = drawInteriorEdges; 02403 ccgdm->useSubsurfUv = useSubsurfUv; 02404 02405 totvert = ccgSubSurf_getNumVerts(ss); 02406 ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap"); 02407 vi = ccgSubSurf_getVertIterator(ss); 02408 for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { 02409 CCGVert *v = ccgVertIterator_getCurrent(vi); 02410 02411 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v; 02412 } 02413 ccgVertIterator_free(vi); 02414 02415 totedge = ccgSubSurf_getNumEdges(ss); 02416 ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap"); 02417 ei = ccgSubSurf_getEdgeIterator(ss); 02418 for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { 02419 CCGEdge *e = ccgEdgeIterator_getCurrent(ei); 02420 02421 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e; 02422 } 02423 02424 totface = ccgSubSurf_getNumFaces(ss); 02425 ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap"); 02426 fi = ccgSubSurf_getFaceIterator(ss); 02427 for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { 02428 CCGFace *f = ccgFaceIterator_getCurrent(fi); 02429 02430 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f; 02431 } 02432 ccgFaceIterator_free(fi); 02433 02434 edgeSize = ccgSubSurf_getEdgeSize(ss); 02435 gridSize = ccgSubSurf_getGridSize(ss); 02436 gridFaces = gridSize - 1; 02437 /*gridSideVerts = gridSize - 2;*/ /*UNUSED*/ 02438 /*gridInternalVerts = gridSideVerts * gridSideVerts; */ /*UNUSED*/ 02439 gridSideEdges = gridSize - 1; 02440 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 02441 02442 calc_ss_weights(gridFaces, &qweight, &tweight); 02443 02444 vertNum = 0; 02445 edgeNum = 0; 02446 faceNum = 0; 02447 02448 /* mvert = dm->getVertArray(dm); - as yet unused */ 02449 medge = dm->getEdgeArray(dm); 02450 mface = dm->getFaceArray(dm); 02451 02452 faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags"); 02453 02454 orig_indices = (int*)ccgdm->dm.getFaceDataArray(&ccgdm->dm, CD_ORIGINDEX); 02455 for(index = 0; index < totface; ++index) { 02456 CCGFace *f = ccgdm->faceMap[index].face; 02457 int numVerts = ccgSubSurf_getFaceNumVerts(f); 02458 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges); 02459 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); 02460 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight; 02461 int S, x, y; 02462 int vertIdx[4]; 02463 02464 ccgdm->faceMap[index].startVert = vertNum; 02465 ccgdm->faceMap[index].startEdge = edgeNum; 02466 ccgdm->faceMap[index].startFace = faceNum; 02467 02468 if(orig_indices) 02469 orig_indices[faceNum] = origIndex; 02470 02471 /* set the face base vert */ 02472 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum; 02473 02474 for(S = 0; S < numVerts; S++) { 02475 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); 02476 02477 vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); 02478 } 02479 02480 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0], 02481 numVerts, vertNum); 02482 ++vertNum; 02483 02484 for(S = 0; S < numVerts; S++) { 02485 int prevS = (S - 1 + numVerts) % numVerts; 02486 int nextS = (S + 1) % numVerts; 02487 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3; 02488 for(x = 1; x < gridFaces; x++) { 02489 float w[4]; 02490 w[prevS] = weight[x][0][0]; 02491 w[S] = weight[x][0][1]; 02492 w[nextS] = weight[x][0][2]; 02493 w[otherS] = weight[x][0][3]; 02494 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 02495 numVerts, vertNum); 02496 ++vertNum; 02497 } 02498 } 02499 02500 for(S = 0; S < numVerts; S++) { 02501 int prevS = (S - 1 + numVerts) % numVerts; 02502 int nextS = (S + 1) % numVerts; 02503 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3; 02504 for(y = 1; y < gridFaces; y++) { 02505 for(x = 1; x < gridFaces; x++) { 02506 float w[4]; 02507 w[prevS] = weight[y * gridFaces + x][0][0]; 02508 w[S] = weight[y * gridFaces + x][0][1]; 02509 w[nextS] = weight[y * gridFaces + x][0][2]; 02510 w[otherS] = weight[y * gridFaces + x][0][3]; 02511 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 02512 numVerts, vertNum); 02513 ++vertNum; 02514 } 02515 } 02516 } 02517 02518 for(S = 0; S < numVerts; S++) { 02519 int prevS = (S - 1 + numVerts) % numVerts; 02520 int nextS = (S + 1) % numVerts; 02521 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3; 02522 02523 weight = (numVerts == 4) ? qweight : tweight; 02524 02525 for(y = 0; y < gridFaces; y++) { 02526 for(x = 0; x < gridFaces; x++) { 02527 FaceVertWeight w; 02528 int j; 02529 02530 for(j = 0; j < 4; ++j) { 02531 w[j][prevS] = (*weight)[j][0]; 02532 w[j][S] = (*weight)[j][1]; 02533 w[j][nextS] = (*weight)[j][2]; 02534 w[j][otherS] = (*weight)[j][3]; 02535 } 02536 02537 DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL, 02538 &w, 1, faceNum); 02539 weight++; 02540 02541 ++faceNum; 02542 } 02543 } 02544 } 02545 02546 faceFlags[index*2] = mface[origIndex].flag; 02547 faceFlags[index*2 + 1] = mface[origIndex].mat_nr; 02548 02549 edgeNum += numFinalEdges; 02550 } 02551 02552 if(useSubsurfUv) { 02553 CustomData *fdata = &ccgdm->dm.faceData; 02554 CustomData *dmfdata = &dm->faceData; 02555 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE); 02556 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE); 02557 02558 for (i=0; i<numlayer && i<dmnumlayer; i++) 02559 set_subsurf_uv(ss, dm, &ccgdm->dm, i); 02560 } 02561 02562 edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "edgeFlags"); 02563 02564 for(index = 0; index < totedge; ++index) { 02565 CCGEdge *e = ccgdm->edgeMap[index].edge; 02566 int numFinalEdges = edgeSize - 1; 02567 int x; 02568 int vertIdx[2]; 02569 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e)); 02570 02571 CCGVert *v; 02572 v = ccgSubSurf_getEdgeVert0(e); 02573 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); 02574 v = ccgSubSurf_getEdgeVert1(e); 02575 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); 02576 02577 ccgdm->edgeMap[index].startVert = vertNum; 02578 ccgdm->edgeMap[index].startEdge = edgeNum; 02579 02580 /* set the edge base vert */ 02581 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum; 02582 02583 for(x = 1; x < edgeSize - 1; x++) { 02584 float w[2]; 02585 w[1] = (float) x / (edgeSize - 1); 02586 w[0] = 1 - w[1]; 02587 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum); 02588 ++vertNum; 02589 } 02590 02591 edgeFlags[index]= medge[edgeIdx].flag; 02592 02593 edgeNum += numFinalEdges; 02594 } 02595 02596 for(index = 0; index < totvert; ++index) { 02597 CCGVert *v = ccgdm->vertMap[index].vert; 02598 int vertIdx; 02599 02600 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); 02601 02602 ccgdm->vertMap[index].startVert = vertNum; 02603 02604 /* set the vert base vert */ 02605 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum; 02606 02607 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1); 02608 02609 ++vertNum; 02610 } 02611 02612 MEM_freeN(qweight); 02613 MEM_freeN(tweight); 02614 02615 return ccgdm; 02616 } 02617 02618 /***/ 02619 02620 struct DerivedMesh *subsurf_make_derived_from_derived( 02621 struct DerivedMesh *dm, 02622 struct SubsurfModifierData *smd, 02623 int useRenderParams, float (*vertCos)[3], 02624 int isFinalCalc, int forEditMode, int inEditMode) 02625 { 02626 int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF; 02627 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr; 02628 int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv; 02629 int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges); 02630 CCGDerivedMesh *result; 02631 02632 if(forEditMode) { 02633 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels; 02634 02635 smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0, 02636 useSimple); 02637 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple); 02638 02639 result = getCCGDerivedMesh(smd->emCache, 02640 drawInteriorEdges, 02641 useSubsurfUv, dm); 02642 } else if(useRenderParams) { 02643 /* Do not use cache in render mode. */ 02644 CCGSubSurf *ss; 02645 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->renderLevels): smd->renderLevels; 02646 02647 if(levels == 0) 02648 return dm; 02649 02650 ss = _getSubSurf(NULL, levels, 0, 1, useSimple); 02651 02652 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); 02653 02654 result = getCCGDerivedMesh(ss, 02655 drawInteriorEdges, useSubsurfUv, dm); 02656 02657 result->freeSS = 1; 02658 } else { 02659 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental); 02660 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr; 02661 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels; 02662 CCGSubSurf *ss; 02663 02664 /* It is quite possible there is a much better place to do this. It 02665 * depends a bit on how rigourously we expect this function to never 02666 * be called in editmode. In semi-theory we could share a single 02667 * cache, but the handles used inside and outside editmode are not 02668 * the same so we would need some way of converting them. Its probably 02669 * not worth the effort. But then why am I even writing this long 02670 * comment that no one will read? Hmmm. - zr 02671 * 02672 * Addendum: we can't really ensure that this is never called in edit 02673 * mode, so now we have a parameter to verify it. - brecht 02674 */ 02675 if(!inEditMode && smd->emCache) { 02676 ccgSubSurf_free(smd->emCache); 02677 smd->emCache = NULL; 02678 } 02679 02680 if(useIncremental && isFinalCalc) { 02681 smd->mCache = ss = _getSubSurf(smd->mCache, levels, 02682 useAging, 0, useSimple); 02683 02684 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); 02685 02686 result = getCCGDerivedMesh(smd->mCache, 02687 drawInteriorEdges, 02688 useSubsurfUv, dm); 02689 } else { 02690 if (smd->mCache && isFinalCalc) { 02691 ccgSubSurf_free(smd->mCache); 02692 smd->mCache = NULL; 02693 } 02694 02695 ss = _getSubSurf(NULL, levels, 0, 1, useSimple); 02696 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); 02697 02698 result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm); 02699 02700 if(isFinalCalc) 02701 smd->mCache = ss; 02702 else 02703 result->freeSS = 1; 02704 } 02705 } 02706 02707 return (DerivedMesh*)result; 02708 } 02709 02710 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 02711 { 02712 /* Finds the subsurf limit positions for the verts in a mesh 02713 * and puts them in an array of floats. Please note that the 02714 * calculated vert positions is incorrect for the verts 02715 * on the boundary of the mesh. 02716 */ 02717 CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0); 02718 float edge_sum[3], face_sum[3]; 02719 CCGVertIterator *vi; 02720 DerivedMesh *dm = CDDM_from_mesh(me, NULL); 02721 02722 ss_sync_from_derivedmesh(ss, dm, NULL, 0); 02723 02724 vi = ccgSubSurf_getVertIterator(ss); 02725 for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { 02726 CCGVert *v = ccgVertIterator_getCurrent(vi); 02727 int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); 02728 int N = ccgSubSurf_getVertNumEdges(v); 02729 int numFaces = ccgSubSurf_getVertNumFaces(v); 02730 float *co; 02731 int i; 02732 02733 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0; 02734 face_sum[0]= face_sum[1]= face_sum[2]= 0.0; 02735 02736 for (i=0; i<N; i++) { 02737 CCGEdge *e = ccgSubSurf_getVertEdge(v, i); 02738 add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1)); 02739 } 02740 for (i=0; i<numFaces; i++) { 02741 CCGFace *f = ccgSubSurf_getVertFace(v, i); 02742 add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f)); 02743 } 02744 02745 /* ad-hoc correction for boundary vertices, to at least avoid them 02746 moving completely out of place (brecht) */ 02747 if(numFaces && numFaces != N) 02748 mul_v3_fl(face_sum, (float)N/(float)numFaces); 02749 02750 co = ccgSubSurf_getVertData(ss, v); 02751 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5)); 02752 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5)); 02753 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5)); 02754 } 02755 ccgVertIterator_free(vi); 02756 02757 ccgSubSurf_free(ss); 02758 02759 dm->release(dm); 02760 } 02761