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