|
Blender
V2.59
|
00001 /* 00002 * $Id: DerivedMesh.c 38890 2011-08-01 06:50:24Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2005 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include <string.h> 00036 00037 00038 #include "MEM_guardedalloc.h" 00039 00040 #include "DNA_cloth_types.h" 00041 #include "DNA_key_types.h" 00042 #include "DNA_meshdata_types.h" 00043 #include "DNA_object_types.h" 00044 #include "DNA_scene_types.h" // N_T 00045 00046 #include "BLI_blenlib.h" 00047 #include "BLI_editVert.h" 00048 #include "BLI_math.h" 00049 #include "BLI_memarena.h" 00050 #include "BLI_pbvh.h" 00051 #include "BLI_utildefines.h" 00052 00053 #include "BKE_cdderivedmesh.h" 00054 #include "BKE_displist.h" 00055 #include "BKE_key.h" 00056 #include "BKE_modifier.h" 00057 #include "BKE_mesh.h" 00058 #include "BKE_object.h" 00059 #include "BKE_paint.h" 00060 #include "BKE_texture.h" 00061 #include "BKE_multires.h" 00062 00063 00064 #include "BLO_sys_types.h" // for intptr_t support 00065 00066 #include "BIF_gl.h" 00067 #include "BIF_glutil.h" 00068 00069 #include "GPU_buffers.h" 00070 #include "GPU_draw.h" 00071 #include "GPU_extensions.h" 00072 #include "GPU_material.h" 00073 00074 #include "ED_sculpt.h" /* for ED_sculpt_modifiers_changed */ 00075 00078 00079 static MVert *dm_getVertArray(DerivedMesh *dm) 00080 { 00081 MVert *mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); 00082 00083 if (!mvert) { 00084 mvert = CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, 00085 dm->getNumVerts(dm)); 00086 CustomData_set_layer_flag(&dm->vertData, CD_MVERT, CD_FLAG_TEMPORARY); 00087 dm->copyVertArray(dm, mvert); 00088 } 00089 00090 return mvert; 00091 } 00092 00093 static MEdge *dm_getEdgeArray(DerivedMesh *dm) 00094 { 00095 MEdge *medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); 00096 00097 if (!medge) { 00098 medge = CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, 00099 dm->getNumEdges(dm)); 00100 CustomData_set_layer_flag(&dm->edgeData, CD_MEDGE, CD_FLAG_TEMPORARY); 00101 dm->copyEdgeArray(dm, medge); 00102 } 00103 00104 return medge; 00105 } 00106 00107 static MFace *dm_getFaceArray(DerivedMesh *dm) 00108 { 00109 MFace *mface = CustomData_get_layer(&dm->faceData, CD_MFACE); 00110 00111 if (!mface) { 00112 mface = CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, 00113 dm->getNumFaces(dm)); 00114 CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY); 00115 dm->copyFaceArray(dm, mface); 00116 } 00117 00118 return mface; 00119 } 00120 00121 static MVert *dm_dupVertArray(DerivedMesh *dm) 00122 { 00123 MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm), 00124 "dm_dupVertArray tmp"); 00125 00126 if(tmp) dm->copyVertArray(dm, tmp); 00127 00128 return tmp; 00129 } 00130 00131 static MEdge *dm_dupEdgeArray(DerivedMesh *dm) 00132 { 00133 MEdge *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumEdges(dm), 00134 "dm_dupEdgeArray tmp"); 00135 00136 if(tmp) dm->copyEdgeArray(dm, tmp); 00137 00138 return tmp; 00139 } 00140 00141 static MFace *dm_dupFaceArray(DerivedMesh *dm) 00142 { 00143 MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumFaces(dm), 00144 "dm_dupFaceArray tmp"); 00145 00146 if(tmp) dm->copyFaceArray(dm, tmp); 00147 00148 return tmp; 00149 } 00150 00151 void DM_init_funcs(DerivedMesh *dm) 00152 { 00153 /* default function implementations */ 00154 dm->getVertArray = dm_getVertArray; 00155 dm->getEdgeArray = dm_getEdgeArray; 00156 dm->getFaceArray = dm_getFaceArray; 00157 dm->dupVertArray = dm_dupVertArray; 00158 dm->dupEdgeArray = dm_dupEdgeArray; 00159 dm->dupFaceArray = dm_dupFaceArray; 00160 00161 dm->getVertData = DM_get_vert_data; 00162 dm->getEdgeData = DM_get_edge_data; 00163 dm->getFaceData = DM_get_face_data; 00164 dm->getVertDataArray = DM_get_vert_data_layer; 00165 dm->getEdgeDataArray = DM_get_edge_data_layer; 00166 dm->getFaceDataArray = DM_get_face_data_layer; 00167 00168 bvhcache_init(&dm->bvhCache); 00169 } 00170 00171 void DM_init(DerivedMesh *dm, DerivedMeshType type, 00172 int numVerts, int numEdges, int numFaces) 00173 { 00174 dm->type = type; 00175 dm->numVertData = numVerts; 00176 dm->numEdgeData = numEdges; 00177 dm->numFaceData = numFaces; 00178 00179 DM_init_funcs(dm); 00180 00181 dm->needsFree = 1; 00182 } 00183 00184 void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, 00185 int numVerts, int numEdges, int numFaces) 00186 { 00187 CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH, 00188 CD_CALLOC, numVerts); 00189 CustomData_copy(&source->edgeData, &dm->edgeData, CD_MASK_DERIVEDMESH, 00190 CD_CALLOC, numEdges); 00191 CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH, 00192 CD_CALLOC, numFaces); 00193 00194 dm->type = type; 00195 dm->numVertData = numVerts; 00196 dm->numEdgeData = numEdges; 00197 dm->numFaceData = numFaces; 00198 00199 DM_init_funcs(dm); 00200 00201 dm->needsFree = 1; 00202 } 00203 00204 int DM_release(DerivedMesh *dm) 00205 { 00206 if (dm->needsFree) { 00207 bvhcache_free(&dm->bvhCache); 00208 GPU_drawobject_free( dm ); 00209 CustomData_free(&dm->vertData, dm->numVertData); 00210 CustomData_free(&dm->edgeData, dm->numEdgeData); 00211 CustomData_free(&dm->faceData, dm->numFaceData); 00212 00213 return 1; 00214 } 00215 else { 00216 CustomData_free_temporary(&dm->vertData, dm->numVertData); 00217 CustomData_free_temporary(&dm->edgeData, dm->numEdgeData); 00218 CustomData_free_temporary(&dm->faceData, dm->numFaceData); 00219 00220 return 0; 00221 } 00222 } 00223 00224 void DM_to_mesh(DerivedMesh *dm, Mesh *me) 00225 { 00226 /* dm might depend on me, so we need to do everything with a local copy */ 00227 Mesh tmp = *me; 00228 int totvert, totedge, totface; 00229 00230 memset(&tmp.vdata, 0, sizeof(tmp.vdata)); 00231 memset(&tmp.edata, 0, sizeof(tmp.edata)); 00232 memset(&tmp.fdata, 0, sizeof(tmp.fdata)); 00233 00234 totvert = tmp.totvert = dm->getNumVerts(dm); 00235 totedge = tmp.totedge = dm->getNumEdges(dm); 00236 totface = tmp.totface = dm->getNumFaces(dm); 00237 00238 CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert); 00239 CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge); 00240 CustomData_copy(&dm->faceData, &tmp.fdata, CD_MASK_MESH, CD_DUPLICATE, totface); 00241 00242 /* not all DerivedMeshes store their verts/edges/faces in CustomData, so 00243 we set them here in case they are missing */ 00244 if(!CustomData_has_layer(&tmp.vdata, CD_MVERT)) 00245 CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, dm->dupVertArray(dm), totvert); 00246 if(!CustomData_has_layer(&tmp.edata, CD_MEDGE)) 00247 CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge); 00248 if(!CustomData_has_layer(&tmp.fdata, CD_MFACE)) 00249 CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface); 00250 00251 /* object had got displacement layer, should copy this layer to save sculpted data */ 00252 /* NOTE: maybe some other layers should be copied? nazgul */ 00253 if(CustomData_has_layer(&me->fdata, CD_MDISPS)) { 00254 if (totface == me->totface) { 00255 MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS); 00256 CustomData_add_layer(&tmp.fdata, CD_MDISPS, CD_DUPLICATE, mdisps, totface); 00257 } 00258 } 00259 00260 mesh_update_customdata_pointers(&tmp); 00261 00262 CustomData_free(&me->vdata, me->totvert); 00263 CustomData_free(&me->edata, me->totedge); 00264 CustomData_free(&me->fdata, me->totface); 00265 00266 /* if the number of verts has changed, remove invalid data */ 00267 if(tmp.totvert != me->totvert) { 00268 if(tmp.key) tmp.key->id.us--; 00269 tmp.key = NULL; 00270 } 00271 00272 *me = tmp; 00273 } 00274 00275 void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb) 00276 { 00277 int a, totvert = dm->getNumVerts(dm); 00278 float *fp; 00279 MVert *mvert; 00280 00281 if(totvert==0 || me->totvert==0 || me->totvert!=totvert) return; 00282 00283 if(kb->data) MEM_freeN(kb->data); 00284 kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data"); 00285 kb->totelem= totvert; 00286 00287 fp= kb->data; 00288 mvert=dm->getVertDataArray(dm, CD_MVERT); 00289 00290 for(a=0; a<kb->totelem; a++, fp+=3, mvert++) { 00291 VECCOPY(fp, mvert->co); 00292 } 00293 } 00294 00295 void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask) 00296 { 00297 CustomData_set_only_copy(&dm->vertData, mask); 00298 CustomData_set_only_copy(&dm->edgeData, mask); 00299 CustomData_set_only_copy(&dm->faceData, mask); 00300 } 00301 00302 void DM_add_vert_layer(DerivedMesh *dm, int type, int alloctype, void *layer) 00303 { 00304 CustomData_add_layer(&dm->vertData, type, alloctype, layer, dm->numVertData); 00305 } 00306 00307 void DM_add_edge_layer(DerivedMesh *dm, int type, int alloctype, void *layer) 00308 { 00309 CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData); 00310 } 00311 00312 void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer) 00313 { 00314 CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numFaceData); 00315 } 00316 00317 void *DM_get_vert_data(DerivedMesh *dm, int index, int type) 00318 { 00319 return CustomData_get(&dm->vertData, index, type); 00320 } 00321 00322 void *DM_get_edge_data(DerivedMesh *dm, int index, int type) 00323 { 00324 return CustomData_get(&dm->edgeData, index, type); 00325 } 00326 00327 void *DM_get_face_data(DerivedMesh *dm, int index, int type) 00328 { 00329 return CustomData_get(&dm->faceData, index, type); 00330 } 00331 00332 void *DM_get_vert_data_layer(DerivedMesh *dm, int type) 00333 { 00334 if(type == CD_MVERT) 00335 return dm->getVertArray(dm); 00336 00337 return CustomData_get_layer(&dm->vertData, type); 00338 } 00339 00340 void *DM_get_edge_data_layer(DerivedMesh *dm, int type) 00341 { 00342 if(type == CD_MEDGE) 00343 return dm->getEdgeArray(dm); 00344 00345 return CustomData_get_layer(&dm->edgeData, type); 00346 } 00347 00348 void *DM_get_face_data_layer(DerivedMesh *dm, int type) 00349 { 00350 if(type == CD_MFACE) 00351 return dm->getFaceArray(dm); 00352 00353 return CustomData_get_layer(&dm->faceData, type); 00354 } 00355 00356 void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data) 00357 { 00358 CustomData_set(&dm->vertData, index, type, data); 00359 } 00360 00361 void DM_set_edge_data(DerivedMesh *dm, int index, int type, void *data) 00362 { 00363 CustomData_set(&dm->edgeData, index, type, data); 00364 } 00365 00366 void DM_set_face_data(DerivedMesh *dm, int index, int type, void *data) 00367 { 00368 CustomData_set(&dm->faceData, index, type, data); 00369 } 00370 00371 void DM_copy_vert_data(DerivedMesh *source, DerivedMesh *dest, 00372 int source_index, int dest_index, int count) 00373 { 00374 CustomData_copy_data(&source->vertData, &dest->vertData, 00375 source_index, dest_index, count); 00376 } 00377 00378 void DM_copy_edge_data(DerivedMesh *source, DerivedMesh *dest, 00379 int source_index, int dest_index, int count) 00380 { 00381 CustomData_copy_data(&source->edgeData, &dest->edgeData, 00382 source_index, dest_index, count); 00383 } 00384 00385 void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest, 00386 int source_index, int dest_index, int count) 00387 { 00388 CustomData_copy_data(&source->faceData, &dest->faceData, 00389 source_index, dest_index, count); 00390 } 00391 00392 void DM_free_vert_data(struct DerivedMesh *dm, int index, int count) 00393 { 00394 CustomData_free_elem(&dm->vertData, index, count); 00395 } 00396 00397 void DM_free_edge_data(struct DerivedMesh *dm, int index, int count) 00398 { 00399 CustomData_free_elem(&dm->edgeData, index, count); 00400 } 00401 00402 void DM_free_face_data(struct DerivedMesh *dm, int index, int count) 00403 { 00404 CustomData_free_elem(&dm->faceData, index, count); 00405 } 00406 00407 void DM_interp_vert_data(DerivedMesh *source, DerivedMesh *dest, 00408 int *src_indices, float *weights, 00409 int count, int dest_index) 00410 { 00411 CustomData_interp(&source->vertData, &dest->vertData, src_indices, 00412 weights, NULL, count, dest_index); 00413 } 00414 00415 void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest, 00416 int *src_indices, 00417 float *weights, EdgeVertWeight *vert_weights, 00418 int count, int dest_index) 00419 { 00420 CustomData_interp(&source->edgeData, &dest->edgeData, src_indices, 00421 weights, (float*)vert_weights, count, dest_index); 00422 } 00423 00424 void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest, 00425 int *src_indices, 00426 float *weights, FaceVertWeight *vert_weights, 00427 int count, int dest_index) 00428 { 00429 CustomData_interp(&source->faceData, &dest->faceData, src_indices, 00430 weights, (float*)vert_weights, count, dest_index); 00431 } 00432 00433 void DM_swap_face_data(DerivedMesh *dm, int index, const int *corner_indices) 00434 { 00435 CustomData_swap(&dm->faceData, index, corner_indices); 00436 } 00437 00439 00440 DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3]) 00441 { 00442 DerivedMesh *dm = CDDM_from_mesh(me, ob); 00443 00444 if(!dm) 00445 return NULL; 00446 00447 if (vertCos) 00448 CDDM_apply_vert_coords(dm, vertCos); 00449 00450 CDDM_calc_normals(dm); 00451 00452 return dm; 00453 } 00454 00456 00457 typedef struct { 00458 DerivedMesh dm; 00459 00460 EditMesh *em; 00461 float (*vertexCos)[3]; 00462 float (*vertexNos)[3]; 00463 float (*faceNos)[3]; 00464 } EditMeshDerivedMesh; 00465 00466 static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) 00467 { 00468 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 00469 EditVert *eve; 00470 int i; 00471 00472 for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) { 00473 if (emdm->vertexCos) { 00474 func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL); 00475 } else { 00476 func(userData, i, eve->co, eve->no, NULL); 00477 } 00478 } 00479 } 00480 static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) 00481 { 00482 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 00483 EditEdge *eed; 00484 int i; 00485 00486 if (emdm->vertexCos) { 00487 EditVert *eve; 00488 00489 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) 00490 eve->tmp.l = (intptr_t) i++; 00491 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) 00492 func(userData, i, emdm->vertexCos[(int) eed->v1->tmp.l], emdm->vertexCos[(int) eed->v2->tmp.l]); 00493 } else { 00494 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) 00495 func(userData, i, eed->v1->co, eed->v2->co); 00496 } 00497 } 00498 static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 00499 { 00500 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 00501 EditEdge *eed; 00502 int i; 00503 00504 if (emdm->vertexCos) { 00505 EditVert *eve; 00506 00507 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) 00508 eve->tmp.l = (intptr_t) i++; 00509 00510 glBegin(GL_LINES); 00511 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { 00512 if(!setDrawOptions || setDrawOptions(userData, i)) { 00513 glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]); 00514 glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]); 00515 } 00516 } 00517 glEnd(); 00518 } else { 00519 glBegin(GL_LINES); 00520 for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { 00521 if(!setDrawOptions || setDrawOptions(userData, i)) { 00522 glVertex3fv(eed->v1->co); 00523 glVertex3fv(eed->v2->co); 00524 } 00525 } 00526 glEnd(); 00527 } 00528 } 00529 static void emDM_drawEdges(DerivedMesh *dm, int UNUSED(drawLooseEdges), int UNUSED(drawAllEdges)) 00530 { 00531 emDM_drawMappedEdges(dm, NULL, NULL); 00532 } 00533 static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) 00534 { 00535 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 00536 EditEdge *eed; 00537 int i; 00538 00539 if (emdm->vertexCos) { 00540 EditVert *eve; 00541 00542 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) 00543 eve->tmp.l = (intptr_t) i++; 00544 00545 glBegin(GL_LINES); 00546 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { 00547 if(!setDrawOptions || setDrawOptions(userData, i)) { 00548 setDrawInterpOptions(userData, i, 0.0); 00549 glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]); 00550 setDrawInterpOptions(userData, i, 1.0); 00551 glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]); 00552 } 00553 } 00554 glEnd(); 00555 } else { 00556 glBegin(GL_LINES); 00557 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { 00558 if(!setDrawOptions || setDrawOptions(userData, i)) { 00559 setDrawInterpOptions(userData, i, 0.0); 00560 glVertex3fv(eed->v1->co); 00561 setDrawInterpOptions(userData, i, 1.0); 00562 glVertex3fv(eed->v2->co); 00563 } 00564 } 00565 glEnd(); 00566 } 00567 } 00568 00569 static void emDM_drawUVEdges(DerivedMesh *dm) 00570 { 00571 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 00572 EditFace *efa; 00573 MTFace *tf; 00574 00575 glBegin(GL_LINES); 00576 for(efa= emdm->em->faces.first; efa; efa= efa->next) { 00577 tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE); 00578 00579 if(tf && !(efa->h)) { 00580 glVertex2fv(tf->uv[0]); 00581 glVertex2fv(tf->uv[1]); 00582 00583 glVertex2fv(tf->uv[1]); 00584 glVertex2fv(tf->uv[2]); 00585 00586 if (!efa->v4) { 00587 glVertex2fv(tf->uv[2]); 00588 glVertex2fv(tf->uv[0]); 00589 } else { 00590 glVertex2fv(tf->uv[2]); 00591 glVertex2fv(tf->uv[3]); 00592 glVertex2fv(tf->uv[3]); 00593 glVertex2fv(tf->uv[0]); 00594 } 00595 } 00596 } 00597 glEnd(); 00598 } 00599 00600 static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3]) 00601 { 00602 if (vertexCos) { 00603 VECCOPY(cent, vertexCos[(int) efa->v1->tmp.l]); 00604 add_v3_v3(cent, vertexCos[(int) efa->v2->tmp.l]); 00605 add_v3_v3(cent, vertexCos[(int) efa->v3->tmp.l]); 00606 if (efa->v4) add_v3_v3(cent, vertexCos[(int) efa->v4->tmp.l]); 00607 } else { 00608 VECCOPY(cent, efa->v1->co); 00609 add_v3_v3(cent, efa->v2->co); 00610 add_v3_v3(cent, efa->v3->co); 00611 if (efa->v4) add_v3_v3(cent, efa->v4->co); 00612 } 00613 00614 if (efa->v4) { 00615 mul_v3_fl(cent, 0.25f); 00616 } else { 00617 mul_v3_fl(cent, 0.33333333333f); 00618 } 00619 } 00620 static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) 00621 { 00622 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 00623 EditVert *eve; 00624 EditFace *efa; 00625 float cent[3]; 00626 int i; 00627 00628 if (emdm->vertexCos) { 00629 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) 00630 eve->tmp.l = (intptr_t) i++; 00631 } 00632 00633 for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { 00634 emDM__calcFaceCent(efa, cent, emdm->vertexCos); 00635 func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n); 00636 } 00637 } 00638 00639 /* note, material function is ignored for now. */ 00640 static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int UNUSED(useColors), int (*setMaterial)(int, void *attribs)) 00641 { 00642 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 00643 EditFace *efa; 00644 int i, draw; 00645 00646 (void)setMaterial; /* unused */ 00647 00648 if (emdm->vertexCos) { 00649 EditVert *eve; 00650 00651 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) 00652 eve->tmp.l = (intptr_t) i++; 00653 00654 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { 00655 int drawSmooth = (efa->flag & ME_SMOOTH); 00656 draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); 00657 if(draw) { 00658 if (draw==2) { /* enabled with stipple */ 00659 glEnable(GL_POLYGON_STIPPLE); 00660 glPolygonStipple(stipple_quarttone); 00661 } 00662 00663 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); 00664 00665 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); 00666 if (!drawSmooth) { 00667 glNormal3fv(emdm->faceNos[i]); 00668 glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]); 00669 glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]); 00670 glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]); 00671 if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]); 00672 } else { 00673 glNormal3fv(emdm->vertexNos[(int) efa->v1->tmp.l]); 00674 glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]); 00675 glNormal3fv(emdm->vertexNos[(int) efa->v2->tmp.l]); 00676 glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]); 00677 glNormal3fv(emdm->vertexNos[(int) efa->v3->tmp.l]); 00678 glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]); 00679 if(efa->v4) { 00680 glNormal3fv(emdm->vertexNos[(int) efa->v4->tmp.l]); 00681 glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]); 00682 } 00683 } 00684 glEnd(); 00685 00686 if (draw==2) 00687 glDisable(GL_POLYGON_STIPPLE); 00688 } 00689 } 00690 } else { 00691 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { 00692 int drawSmooth = (efa->flag & ME_SMOOTH); 00693 draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth); 00694 if(draw) { 00695 if (draw==2) { /* enabled with stipple */ 00696 glEnable(GL_POLYGON_STIPPLE); 00697 glPolygonStipple(stipple_quarttone); 00698 } 00699 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); 00700 00701 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); 00702 if (!drawSmooth) { 00703 glNormal3fv(efa->n); 00704 glVertex3fv(efa->v1->co); 00705 glVertex3fv(efa->v2->co); 00706 glVertex3fv(efa->v3->co); 00707 if(efa->v4) glVertex3fv(efa->v4->co); 00708 } else { 00709 glNormal3fv(efa->v1->no); 00710 glVertex3fv(efa->v1->co); 00711 glNormal3fv(efa->v2->no); 00712 glVertex3fv(efa->v2->co); 00713 glNormal3fv(efa->v3->no); 00714 glVertex3fv(efa->v3->co); 00715 if(efa->v4) { 00716 glNormal3fv(efa->v4->no); 00717 glVertex3fv(efa->v4->co); 00718 } 00719 } 00720 glEnd(); 00721 00722 if (draw==2) 00723 glDisable(GL_POLYGON_STIPPLE); 00724 } 00725 } 00726 } 00727 } 00728 00729 static void emDM_drawFacesTex_common(DerivedMesh *dm, 00730 int (*drawParams)(MTFace *tface, MCol *mcol, int matnr), 00731 int (*drawParamsMapped)(void *userData, int index), 00732 void *userData) 00733 { 00734 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 00735 EditMesh *em= emdm->em; 00736 float (*vertexCos)[3]= emdm->vertexCos; 00737 float (*vertexNos)[3]= emdm->vertexNos; 00738 EditFace *efa; 00739 int i; 00740 00741 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ 00742 glShadeModel(GL_SMOOTH); 00743 00744 if (vertexCos) { 00745 EditVert *eve; 00746 00747 for (i=0,eve=em->verts.first; eve; eve= eve->next) 00748 eve->tmp.l = (intptr_t) i++; 00749 00750 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { 00751 MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); 00752 MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL); 00753 unsigned char *cp= NULL; 00754 int drawSmooth= (efa->flag & ME_SMOOTH); 00755 int flag; 00756 00757 if(drawParams) 00758 flag= drawParams(tf, mcol, efa->mat_nr); 00759 else if(drawParamsMapped) 00760 flag= drawParamsMapped(userData, i); 00761 else 00762 flag= 1; 00763 00764 if(flag != 0) { /* flag 0 == the face is hidden or invisible */ 00765 00766 /* we always want smooth here since otherwise vertex colors dont interpolate */ 00767 if (mcol) { 00768 if (flag==1) { 00769 cp= (unsigned char*)mcol; 00770 } 00771 } else { 00772 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); 00773 } 00774 00775 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); 00776 if (!drawSmooth) { 00777 glNormal3fv(emdm->faceNos[i]); 00778 00779 if(tf) glTexCoord2fv(tf->uv[0]); 00780 if(cp) glColor3ub(cp[3], cp[2], cp[1]); 00781 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); 00782 00783 if(tf) glTexCoord2fv(tf->uv[1]); 00784 if(cp) glColor3ub(cp[7], cp[6], cp[5]); 00785 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); 00786 00787 if(tf) glTexCoord2fv(tf->uv[2]); 00788 if(cp) glColor3ub(cp[11], cp[10], cp[9]); 00789 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); 00790 00791 if(efa->v4) { 00792 if(tf) glTexCoord2fv(tf->uv[3]); 00793 if(cp) glColor3ub(cp[15], cp[14], cp[13]); 00794 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); 00795 } 00796 } else { 00797 if(tf) glTexCoord2fv(tf->uv[0]); 00798 if(cp) glColor3ub(cp[3], cp[2], cp[1]); 00799 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]); 00800 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); 00801 00802 if(tf) glTexCoord2fv(tf->uv[1]); 00803 if(cp) glColor3ub(cp[7], cp[6], cp[5]); 00804 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]); 00805 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); 00806 00807 if(tf) glTexCoord2fv(tf->uv[2]); 00808 if(cp) glColor3ub(cp[11], cp[10], cp[9]); 00809 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]); 00810 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); 00811 00812 if(efa->v4) { 00813 if(tf) glTexCoord2fv(tf->uv[3]); 00814 if(cp) glColor3ub(cp[15], cp[14], cp[13]); 00815 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]); 00816 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); 00817 } 00818 } 00819 glEnd(); 00820 } 00821 } 00822 } else { 00823 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { 00824 MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); 00825 MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL); 00826 unsigned char *cp= NULL; 00827 int drawSmooth= (efa->flag & ME_SMOOTH); 00828 int flag; 00829 00830 if(drawParams) 00831 flag= drawParams(tf, mcol, efa->mat_nr); 00832 else if(drawParamsMapped) 00833 flag= drawParamsMapped(userData, i); 00834 else 00835 flag= 1; 00836 00837 if(flag != 0) { /* flag 0 == the face is hidden or invisible */ 00838 /* we always want smooth here since otherwise vertex colors dont interpolate */ 00839 if (mcol) { 00840 if (flag==1) { 00841 cp= (unsigned char*)mcol; 00842 } 00843 } else { 00844 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); 00845 } 00846 00847 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); 00848 if (!drawSmooth) { 00849 glNormal3fv(efa->n); 00850 00851 if(tf) glTexCoord2fv(tf->uv[0]); 00852 if(cp) glColor3ub(cp[3], cp[2], cp[1]); 00853 glVertex3fv(efa->v1->co); 00854 00855 if(tf) glTexCoord2fv(tf->uv[1]); 00856 if(cp) glColor3ub(cp[7], cp[6], cp[5]); 00857 glVertex3fv(efa->v2->co); 00858 00859 if(tf) glTexCoord2fv(tf->uv[2]); 00860 if(cp) glColor3ub(cp[11], cp[10], cp[9]); 00861 glVertex3fv(efa->v3->co); 00862 00863 if(efa->v4) { 00864 if(tf) glTexCoord2fv(tf->uv[3]); 00865 if(cp) glColor3ub(cp[15], cp[14], cp[13]); 00866 glVertex3fv(efa->v4->co); 00867 } 00868 } else { 00869 if(tf) glTexCoord2fv(tf->uv[0]); 00870 if(cp) glColor3ub(cp[3], cp[2], cp[1]); 00871 glNormal3fv(efa->v1->no); 00872 glVertex3fv(efa->v1->co); 00873 00874 if(tf) glTexCoord2fv(tf->uv[1]); 00875 if(cp) glColor3ub(cp[7], cp[6], cp[5]); 00876 glNormal3fv(efa->v2->no); 00877 glVertex3fv(efa->v2->co); 00878 00879 if(tf) glTexCoord2fv(tf->uv[2]); 00880 if(cp) glColor3ub(cp[11], cp[10], cp[9]); 00881 glNormal3fv(efa->v3->no); 00882 glVertex3fv(efa->v3->co); 00883 00884 if(efa->v4) { 00885 if(tf) glTexCoord2fv(tf->uv[3]); 00886 if(cp) glColor3ub(cp[15], cp[14], cp[13]); 00887 glNormal3fv(efa->v4->no); 00888 glVertex3fv(efa->v4->co); 00889 } 00890 } 00891 glEnd(); 00892 } 00893 } 00894 } 00895 } 00896 00897 static void emDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr)) 00898 { 00899 emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL); 00900 } 00901 00902 static void emDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 00903 { 00904 emDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData); 00905 } 00906 00907 static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, 00908 int (*setMaterial)(int, void *attribs), 00909 int (*setDrawOptions)(void *userData, int index), void *userData) 00910 { 00911 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 00912 EditMesh *em= emdm->em; 00913 float (*vertexCos)[3]= emdm->vertexCos; 00914 float (*vertexNos)[3]= emdm->vertexNos; 00915 EditVert *eve; 00916 EditFace *efa; 00917 DMVertexAttribs attribs= {{{0}}}; 00918 GPUVertexAttribs gattribs; 00919 MTFace *tf; 00920 int transp, new_transp, orig_transp, tfoffset; 00921 int i, b, matnr, new_matnr, dodraw, layer; 00922 00923 dodraw = 0; 00924 matnr = -1; 00925 00926 transp = GPU_get_material_blend_mode(); 00927 orig_transp = transp; 00928 layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); 00929 tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; 00930 00931 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ 00932 glShadeModel(GL_SMOOTH); 00933 00934 for (i=0,eve=em->verts.first; eve; eve= eve->next) 00935 eve->tmp.l = (intptr_t) i++; 00936 00937 #define PASSATTRIB(efa, eve, vert) { \ 00938 if(attribs.totorco) { \ 00939 float *orco = attribs.orco.array[eve->tmp.l]; \ 00940 glVertexAttrib3fvARB(attribs.orco.glIndex, orco); \ 00941 } \ 00942 for(b = 0; b < attribs.tottface; b++) { \ 00943 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset); \ 00944 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]); \ 00945 } \ 00946 for(b = 0; b < attribs.totmcol; b++) { \ 00947 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset); \ 00948 GLubyte col[4]; \ 00949 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \ 00950 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \ 00951 } \ 00952 if(attribs.tottang) { \ 00953 float *tang = attribs.tang.array[i*4 + vert]; \ 00954 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \ 00955 } \ 00956 } 00957 00958 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { 00959 int drawSmooth= (efa->flag & ME_SMOOTH); 00960 00961 if(setDrawOptions && !setDrawOptions(userData, i)) 00962 continue; 00963 00964 new_matnr = efa->mat_nr + 1; 00965 if(new_matnr != matnr) { 00966 dodraw = setMaterial(matnr = new_matnr, &gattribs); 00967 if(dodraw) 00968 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); 00969 } 00970 00971 if(tfoffset != -1) { 00972 tf = (MTFace*)((char*)efa->data)+tfoffset; 00973 new_transp = tf->transp; 00974 00975 if(new_transp != transp) { 00976 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID) 00977 GPU_set_material_blend_mode(orig_transp); 00978 else 00979 GPU_set_material_blend_mode(new_transp); 00980 transp = new_transp; 00981 } 00982 } 00983 00984 if(dodraw) { 00985 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); 00986 if (!drawSmooth) { 00987 if(vertexCos) glNormal3fv(emdm->faceNos[i]); 00988 else glNormal3fv(efa->n); 00989 00990 PASSATTRIB(efa, efa->v1, 0); 00991 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); 00992 else glVertex3fv(efa->v1->co); 00993 00994 PASSATTRIB(efa, efa->v2, 1); 00995 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); 00996 else glVertex3fv(efa->v2->co); 00997 00998 PASSATTRIB(efa, efa->v3, 2); 00999 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); 01000 else glVertex3fv(efa->v3->co); 01001 01002 if(efa->v4) { 01003 PASSATTRIB(efa, efa->v4, 3); 01004 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); 01005 else glVertex3fv(efa->v4->co); 01006 } 01007 } else { 01008 PASSATTRIB(efa, efa->v1, 0); 01009 if(vertexCos) { 01010 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]); 01011 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); 01012 } 01013 else { 01014 glNormal3fv(efa->v1->no); 01015 glVertex3fv(efa->v1->co); 01016 } 01017 01018 PASSATTRIB(efa, efa->v2, 1); 01019 if(vertexCos) { 01020 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]); 01021 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); 01022 } 01023 else { 01024 glNormal3fv(efa->v2->no); 01025 glVertex3fv(efa->v2->co); 01026 } 01027 01028 PASSATTRIB(efa, efa->v3, 2); 01029 if(vertexCos) { 01030 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]); 01031 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); 01032 } 01033 else { 01034 glNormal3fv(efa->v3->no); 01035 glVertex3fv(efa->v3->co); 01036 } 01037 01038 if(efa->v4) { 01039 PASSATTRIB(efa, efa->v4, 3); 01040 if(vertexCos) { 01041 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]); 01042 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); 01043 } 01044 else { 01045 glNormal3fv(efa->v4->no); 01046 glVertex3fv(efa->v4->co); 01047 } 01048 } 01049 } 01050 glEnd(); 01051 } 01052 } 01053 } 01054 01055 static void emDM_drawFacesGLSL(DerivedMesh *dm, 01056 int (*setMaterial)(int, void *attribs)) 01057 { 01058 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); 01059 } 01060 01061 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) 01062 { 01063 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 01064 EditVert *eve; 01065 int i; 01066 01067 if (emdm->em->verts.first) { 01068 for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) { 01069 if (emdm->vertexCos) { 01070 DO_MINMAX(emdm->vertexCos[i], min_r, max_r); 01071 } else { 01072 DO_MINMAX(eve->co, min_r, max_r); 01073 } 01074 } 01075 } else { 01076 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0; 01077 } 01078 } 01079 static int emDM_getNumVerts(DerivedMesh *dm) 01080 { 01081 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 01082 01083 return BLI_countlist(&emdm->em->verts); 01084 } 01085 01086 static int emDM_getNumEdges(DerivedMesh *dm) 01087 { 01088 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 01089 01090 return BLI_countlist(&emdm->em->edges); 01091 } 01092 01093 static int emDM_getNumFaces(DerivedMesh *dm) 01094 { 01095 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 01096 01097 return BLI_countlist(&emdm->em->faces); 01098 } 01099 01100 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3]) 01101 { 01102 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 01103 EditVert *eve; 01104 int i; 01105 01106 for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) { 01107 if (emdm->vertexCos) { 01108 copy_v3_v3(cos_r[i], emdm->vertexCos[i]); 01109 } else { 01110 copy_v3_v3(cos_r[i], eve->co); 01111 } 01112 } 01113 } 01114 01115 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r) 01116 { 01117 EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first; 01118 int i; 01119 01120 for(i = 0; i < index; ++i) ev = ev->next; 01121 01122 VECCOPY(vert_r->co, ev->co); 01123 01124 normal_float_to_short_v3(vert_r->no, ev->no); 01125 01126 /* TODO what to do with vert_r->flag? */ 01127 vert_r->bweight = (unsigned char) (ev->bweight*255.0f); 01128 } 01129 01130 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r) 01131 { 01132 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em; 01133 EditEdge *ee = em->edges.first; 01134 EditVert *ev, *v1, *v2; 01135 int i; 01136 01137 for(i = 0; i < index; ++i) ee = ee->next; 01138 01139 edge_r->crease = (unsigned char) (ee->crease*255.0f); 01140 edge_r->bweight = (unsigned char) (ee->bweight*255.0f); 01141 /* TODO what to do with edge_r->flag? */ 01142 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER; 01143 if (ee->seam) edge_r->flag |= ME_SEAM; 01144 if (ee->sharp) edge_r->flag |= ME_SHARP; 01145 #if 0 01146 /* this needs setup of f2 field */ 01147 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE; 01148 #endif 01149 01150 /* goddamn, we have to search all verts to find indices */ 01151 v1 = ee->v1; 01152 v2 = ee->v2; 01153 for(i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) { 01154 if(ev == v1) { 01155 edge_r->v1 = i; 01156 v1 = NULL; 01157 } 01158 if(ev == v2) { 01159 edge_r->v2 = i; 01160 v2 = NULL; 01161 } 01162 } 01163 } 01164 01165 static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r) 01166 { 01167 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em; 01168 EditFace *ef = em->faces.first; 01169 EditVert *ev, *v1, *v2, *v3, *v4; 01170 int i; 01171 01172 for(i = 0; i < index; ++i) ef = ef->next; 01173 01174 face_r->mat_nr = ef->mat_nr; 01175 face_r->flag = ef->flag; 01176 01177 /* goddamn, we have to search all verts to find indices */ 01178 v1 = ef->v1; 01179 v2 = ef->v2; 01180 v3 = ef->v3; 01181 v4 = ef->v4; 01182 if(!v4) face_r->v4 = 0; 01183 01184 for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4; 01185 i++, ev = ev->next) { 01186 if(ev == v1) { 01187 face_r->v1 = i; 01188 v1 = NULL; 01189 } 01190 if(ev == v2) { 01191 face_r->v2 = i; 01192 v2 = NULL; 01193 } 01194 if(ev == v3) { 01195 face_r->v3 = i; 01196 v3 = NULL; 01197 } 01198 if(ev == v4) { 01199 face_r->v4 = i; 01200 v4 = NULL; 01201 } 01202 } 01203 01204 test_index_face(face_r, NULL, 0, ef->v4?4:3); 01205 } 01206 01207 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) 01208 { 01209 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 01210 EditVert *ev = emdm->em->verts.first; 01211 int i; 01212 01213 for(i=0; ev; ev = ev->next, ++vert_r, ++i) { 01214 if(emdm->vertexCos) 01215 copy_v3_v3(vert_r->co, emdm->vertexCos[i]); 01216 else 01217 copy_v3_v3(vert_r->co, ev->co); 01218 01219 normal_float_to_short_v3(vert_r->no, ev->no); 01220 01221 /* TODO what to do with vert_r->flag? */ 01222 vert_r->flag = 0; 01223 vert_r->bweight = (unsigned char) (ev->bweight*255.0f); 01224 } 01225 } 01226 01227 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r) 01228 { 01229 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em; 01230 EditEdge *ee = em->edges.first; 01231 EditVert *ev; 01232 int i; 01233 01234 /* store vertex indices in tmp union */ 01235 for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i) 01236 ev->tmp.l = (intptr_t) i; 01237 01238 for( ; ee; ee = ee->next, ++edge_r) { 01239 edge_r->crease = (unsigned char) (ee->crease*255.0f); 01240 edge_r->bweight = (unsigned char) (ee->bweight*255.0f); 01241 /* TODO what to do with edge_r->flag? */ 01242 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER; 01243 if (ee->seam) edge_r->flag |= ME_SEAM; 01244 if (ee->sharp) edge_r->flag |= ME_SHARP; 01245 #if 0 01246 /* this needs setup of f2 field */ 01247 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE; 01248 #endif 01249 01250 edge_r->v1 = (int)ee->v1->tmp.l; 01251 edge_r->v2 = (int)ee->v2->tmp.l; 01252 } 01253 } 01254 01255 static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r) 01256 { 01257 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em; 01258 EditFace *ef = em->faces.first; 01259 EditVert *ev; 01260 int i; 01261 01262 /* store vertexes indices in tmp union */ 01263 for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i) 01264 ev->tmp.l = (intptr_t) i; 01265 01266 for( ; ef; ef = ef->next, ++face_r) { 01267 face_r->mat_nr = ef->mat_nr; 01268 face_r->flag = ef->flag; 01269 01270 face_r->v1 = (int)ef->v1->tmp.l; 01271 face_r->v2 = (int)ef->v2->tmp.l; 01272 face_r->v3 = (int)ef->v3->tmp.l; 01273 if(ef->v4) face_r->v4 = (int)ef->v4->tmp.l; 01274 else face_r->v4 = 0; 01275 01276 test_index_face(face_r, NULL, 0, ef->v4?4:3); 01277 } 01278 } 01279 01280 static void *emDM_getFaceDataArray(DerivedMesh *dm, int type) 01281 { 01282 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 01283 EditMesh *em= emdm->em; 01284 EditFace *efa; 01285 char *data, *emdata; 01286 void *datalayer; 01287 int index, size; 01288 01289 datalayer = DM_get_face_data_layer(dm, type); 01290 if(datalayer) 01291 return datalayer; 01292 01293 /* layers are store per face for editmesh, we convert to a temporary 01294 * data layer array in the derivedmesh when these are requested */ 01295 if(type == CD_MTFACE || type == CD_MCOL) { 01296 index = CustomData_get_layer_index(&em->fdata, type); 01297 01298 if(index != -1) { 01299 /* int offset = em->fdata.layers[index].offset; */ /* UNUSED */ 01300 size = CustomData_sizeof(type); 01301 01302 DM_add_face_layer(dm, type, CD_CALLOC, NULL); 01303 index = CustomData_get_layer_index(&dm->faceData, type); 01304 dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY; 01305 01306 data = datalayer = DM_get_face_data_layer(dm, type); 01307 for(efa=em->faces.first; efa; efa=efa->next, data+=size) { 01308 emdata = CustomData_em_get(&em->fdata, efa->data, type); 01309 memcpy(data, emdata, size); 01310 } 01311 } 01312 } 01313 01314 return datalayer; 01315 } 01316 01317 static void emDM_release(DerivedMesh *dm) 01318 { 01319 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; 01320 01321 if (DM_release(dm)) { 01322 if (emdm->vertexCos) { 01323 MEM_freeN(emdm->vertexCos); 01324 MEM_freeN(emdm->vertexNos); 01325 MEM_freeN(emdm->faceNos); 01326 } 01327 01328 MEM_freeN(emdm); 01329 } 01330 } 01331 01332 DerivedMesh *editmesh_get_derived(EditMesh *em, float (*vertexCos)[3]) 01333 { 01334 EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm"); 01335 01336 DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts), 01337 BLI_countlist(&em->edges), BLI_countlist(&em->faces)); 01338 01339 emdm->dm.getMinMax = emDM_getMinMax; 01340 01341 emdm->dm.getNumVerts = emDM_getNumVerts; 01342 emdm->dm.getNumEdges = emDM_getNumEdges; 01343 emdm->dm.getNumFaces = emDM_getNumFaces; 01344 01345 emdm->dm.getVertCos = emDM_getVertCos; 01346 01347 emdm->dm.getVert = emDM_getVert; 01348 emdm->dm.getEdge = emDM_getEdge; 01349 emdm->dm.getFace = emDM_getFace; 01350 emdm->dm.copyVertArray = emDM_copyVertArray; 01351 emdm->dm.copyEdgeArray = emDM_copyEdgeArray; 01352 emdm->dm.copyFaceArray = emDM_copyFaceArray; 01353 emdm->dm.getFaceDataArray = emDM_getFaceDataArray; 01354 01355 emdm->dm.foreachMappedVert = emDM_foreachMappedVert; 01356 emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge; 01357 emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter; 01358 01359 emdm->dm.drawEdges = emDM_drawEdges; 01360 emdm->dm.drawMappedEdges = emDM_drawMappedEdges; 01361 emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp; 01362 emdm->dm.drawMappedFaces = emDM_drawMappedFaces; 01363 emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex; 01364 emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL; 01365 emdm->dm.drawFacesTex = emDM_drawFacesTex; 01366 emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL; 01367 emdm->dm.drawUVEdges = emDM_drawUVEdges; 01368 01369 emdm->dm.release = emDM_release; 01370 01371 emdm->em = em; 01372 emdm->vertexCos = vertexCos; 01373 01374 if(CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) { 01375 EditVert *eve; 01376 int i; 01377 01378 DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL); 01379 01380 for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i) 01381 DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT, 01382 CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT)); 01383 } 01384 01385 if(vertexCos) { 01386 EditVert *eve; 01387 EditFace *efa; 01388 int totface = BLI_countlist(&em->faces); 01389 int i; 01390 01391 for (i=0,eve=em->verts.first; eve; eve= eve->next) 01392 eve->tmp.l = (intptr_t) i++; 01393 01394 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno"); 01395 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno"); 01396 01397 for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) { 01398 float *v1 = vertexCos[(int) efa->v1->tmp.l]; 01399 float *v2 = vertexCos[(int) efa->v2->tmp.l]; 01400 float *v3 = vertexCos[(int) efa->v3->tmp.l]; 01401 float *no = emdm->faceNos[i]; 01402 01403 if(efa->v4) { 01404 float *v4 = vertexCos[(int) efa->v4->tmp.l]; 01405 01406 normal_quad_v3( no,v1, v2, v3, v4); 01407 add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no); 01408 } 01409 else { 01410 normal_tri_v3( no,v1, v2, v3); 01411 } 01412 01413 add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no); 01414 add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no); 01415 add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no); 01416 } 01417 01418 for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) { 01419 float *no = emdm->vertexNos[i]; 01420 /* following Mesh convention; we use vertex coordinate itself 01421 * for normal in this case */ 01422 if (normalize_v3(no) == 0.0f) { 01423 normalize_v3_v3(no, vertexCos[i]); 01424 } 01425 } 01426 } 01427 01428 return (DerivedMesh*) emdm; 01429 } 01430 01431 /***/ 01432 01433 DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, ModifierData *md) 01434 { 01435 Mesh *me = ob->data; 01436 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 01437 DerivedMesh *dm; 01438 01439 md->scene= scene; 01440 01441 if (!(md->mode&eModifierMode_Realtime)) return NULL; 01442 if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL; 01443 01444 if (mti->type==eModifierTypeType_OnlyDeform) { 01445 int numVerts; 01446 float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts); 01447 01448 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, 0, 0); 01449 dm = mesh_create_derived(me, ob, deformedVerts); 01450 01451 MEM_freeN(deformedVerts); 01452 } else { 01453 DerivedMesh *tdm = mesh_create_derived(me, ob, NULL); 01454 dm = mti->applyModifier(md, ob, tdm, 0, 0); 01455 01456 if(tdm != dm) tdm->release(tdm); 01457 } 01458 01459 return dm; 01460 } 01461 01462 static float *get_editmesh_orco_verts(EditMesh *em) 01463 { 01464 EditVert *eve; 01465 float *orco; 01466 int a, totvert; 01467 01468 /* these may not really be the orco's, but it's only for preview. 01469 * could be solver better once, but isn't simple */ 01470 01471 totvert= 0; 01472 for(eve=em->verts.first; eve; eve=eve->next) 01473 totvert++; 01474 01475 orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco"); 01476 01477 for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3) 01478 VECCOPY(orco+a, eve->co); 01479 01480 return orco; 01481 } 01482 01483 /* orco custom data layer */ 01484 01485 static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free) 01486 { 01487 *free= 0; 01488 01489 if(layer == CD_ORCO) { 01490 /* get original coordinates */ 01491 *free= 1; 01492 01493 if(em) 01494 return (float(*)[3])get_editmesh_orco_verts(em); 01495 else 01496 return (float(*)[3])get_mesh_orco_verts(ob); 01497 } 01498 else if(layer == CD_CLOTH_ORCO) { 01499 /* apply shape key for cloth, this should really be solved 01500 by a more flexible customdata system, but not simple */ 01501 if(!em) { 01502 ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); 01503 KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest); 01504 01505 if(kb->data) 01506 return kb->data; 01507 } 01508 01509 return NULL; 01510 } 01511 01512 return NULL; 01513 } 01514 01515 static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer) 01516 { 01517 DerivedMesh *dm; 01518 float (*orco)[3]; 01519 int free; 01520 01521 if(em) dm= CDDM_from_editmesh(em, me); 01522 else dm= CDDM_from_mesh(me, ob); 01523 01524 orco= get_orco_coords_dm(ob, em, layer, &free); 01525 01526 if(orco) { 01527 CDDM_apply_vert_coords(dm, orco); 01528 if(free) MEM_freeN(orco); 01529 } 01530 01531 CDDM_calc_normals(dm); 01532 01533 return dm; 01534 } 01535 01536 static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm, int layer) 01537 { 01538 float (*orco)[3], (*layerorco)[3]; 01539 int totvert, free; 01540 01541 totvert= dm->getNumVerts(dm); 01542 01543 if(orcodm) { 01544 orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco"); 01545 free= 1; 01546 01547 if(orcodm->getNumVerts(orcodm) == totvert) 01548 orcodm->getVertCos(orcodm, orco); 01549 else 01550 dm->getVertCos(dm, orco); 01551 } 01552 else 01553 orco= get_orco_coords_dm(ob, em, layer, &free); 01554 01555 if(orco) { 01556 if(layer == CD_ORCO) 01557 transform_mesh_orco_verts(ob->data, orco, totvert, 0); 01558 01559 if(!(layerorco = DM_get_vert_data_layer(dm, layer))) { 01560 DM_add_vert_layer(dm, layer, CD_CALLOC, NULL); 01561 layerorco = DM_get_vert_data_layer(dm, layer); 01562 } 01563 01564 memcpy(layerorco, orco, sizeof(float)*3*totvert); 01565 if(free) MEM_freeN(orco); 01566 } 01567 } 01568 01569 /* weight paint colors */ 01570 01571 /* Something of a hack, at the moment deal with weightpaint 01572 * by tucking into colors during modifier eval, only in 01573 * wpaint mode. Works ok but need to make sure recalc 01574 * happens on enter/exit wpaint. 01575 */ 01576 01577 void weight_to_rgb(float input, float *fr, float *fg, float *fb) 01578 { 01579 float blend; 01580 01581 blend= ((input/2.0f)+0.5f); 01582 01583 if (input<=0.25f){ // blue->cyan 01584 *fr= 0.0f; 01585 *fg= blend*input*4.0f; 01586 *fb= blend; 01587 } 01588 else if (input<=0.50f){ // cyan->green 01589 *fr= 0.0f; 01590 *fg= blend; 01591 *fb= blend*(1.0f-((input-0.25f)*4.0f)); 01592 } 01593 else if (input <= 0.75f){ // green->yellow 01594 *fr= blend * ((input-0.50f)*4.0f); 01595 *fg= blend; 01596 *fb= 0.0f; 01597 } 01598 else if (input <= 1.0f){ // yellow->red 01599 *fr= blend; 01600 *fg= blend * (1.0f-((input-0.75f)*4.0f)); 01601 *fb= 0.0f; 01602 } 01603 } 01604 01605 static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col) 01606 { 01607 Mesh *me = ob->data; 01608 float colf[4], input = 0.0f; 01609 int i; 01610 01611 if (me->dvert) { 01612 for (i=0; i<me->dvert[vert].totweight; i++) 01613 if (me->dvert[vert].dw[i].def_nr==ob->actdef-1) 01614 input+=me->dvert[vert].dw[i].weight; 01615 } 01616 01617 CLAMP(input, 0.0f, 1.0f); 01618 01619 if(coba) 01620 do_colorband(coba, input, colf); 01621 else 01622 weight_to_rgb(input, colf, colf+1, colf+2); 01623 01624 col[3] = (unsigned char)(colf[0] * 255.0f); 01625 col[2] = (unsigned char)(colf[1] * 255.0f); 01626 col[1] = (unsigned char)(colf[2] * 255.0f); 01627 col[0] = 255; 01628 } 01629 01630 static ColorBand *stored_cb= NULL; 01631 01632 void vDM_ColorBand_store(ColorBand *coba) 01633 { 01634 stored_cb= coba; 01635 } 01636 01637 static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm) 01638 { 01639 Mesh *me = ob->data; 01640 MFace *mf = me->mface; 01641 ColorBand *coba= stored_cb; /* warning, not a local var */ 01642 unsigned char *wtcol; 01643 int i; 01644 01645 wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap"); 01646 01647 memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4); 01648 for (i=0; i<me->totface; i++, mf++) { 01649 calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]); 01650 calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]); 01651 calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]); 01652 if (mf->v4) 01653 calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); 01654 } 01655 01656 CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData); 01657 } 01658 01659 /* new value for useDeform -1 (hack for the gameengine): 01660 * - apply only the modifier stack of the object, skipping the virtual modifiers, 01661 * - don't apply the key 01662 * - apply deform modifiers and input vertexco 01663 */ 01664 static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3], 01665 DerivedMesh **deform_r, DerivedMesh **final_r, 01666 int useRenderParams, int useDeform, 01667 int needMapping, CustomDataMask dataMask, int index, int useCache) 01668 { 01669 Mesh *me = ob->data; 01670 ModifierData *firstmd, *md; 01671 LinkNode *datamasks, *curr; 01672 CustomDataMask mask, nextmask; 01673 float (*deformedVerts)[3] = NULL; 01674 DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm; 01675 int numVerts = me->totvert; 01676 int required_mode; 01677 int isPrevDeform= FALSE; 01678 int skipVirtualArmature = (useDeform < 0); 01679 MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0); 01680 int has_multires = mmd != NULL, multires_applied = 0; 01681 int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt; 01682 01683 if(mmd && !mmd->sculptlvl) 01684 has_multires = 0; 01685 01686 if(!skipVirtualArmature) { 01687 firstmd = modifiers_getVirtualModifierList(ob); 01688 } 01689 else { 01690 /* game engine exception */ 01691 firstmd = ob->modifiers.first; 01692 if(firstmd && firstmd->type == eModifierType_Armature) 01693 firstmd = firstmd->next; 01694 } 01695 01696 md = firstmd; 01697 01698 modifiers_clearErrors(ob); 01699 01700 if(useRenderParams) required_mode = eModifierMode_Render; 01701 else required_mode = eModifierMode_Realtime; 01702 01703 datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); 01704 curr = datamasks; 01705 01706 if(deform_r) *deform_r = NULL; 01707 *final_r = NULL; 01708 01709 if(useDeform) { 01710 if(inputVertexCos) 01711 deformedVerts = inputVertexCos; 01712 01713 /* Apply all leading deforming modifiers */ 01714 for(;md; md = md->next, curr = curr->next) { 01715 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 01716 01717 md->scene= scene; 01718 01719 if(!modifier_isEnabled(scene, md, required_mode)) continue; 01720 if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; 01721 01722 if(mti->type == eModifierTypeType_OnlyDeform) { 01723 if(!deformedVerts) 01724 deformedVerts = mesh_getVertexCos(me, &numVerts); 01725 01726 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, useRenderParams, useDeform); 01727 } else { 01728 break; 01729 } 01730 01731 /* grab modifiers until index i */ 01732 if((index >= 0) && (modifiers_indexInObject(ob, md) >= index)) 01733 break; 01734 } 01735 01736 /* Result of all leading deforming modifiers is cached for 01737 * places that wish to use the original mesh but with deformed 01738 * coordinates (vpaint, etc.) 01739 */ 01740 if (deform_r) { 01741 *deform_r = CDDM_from_mesh(me, ob); 01742 01743 if(deformedVerts) { 01744 CDDM_apply_vert_coords(*deform_r, deformedVerts); 01745 CDDM_calc_normals(*deform_r); 01746 } 01747 } 01748 } else { 01749 /* default behaviour for meshes */ 01750 if(inputVertexCos) 01751 deformedVerts = inputVertexCos; 01752 else 01753 deformedVerts = mesh_getVertexCos(me, &numVerts); 01754 } 01755 01756 01757 /* Now apply all remaining modifiers. If useDeform is off then skip 01758 * OnlyDeform ones. 01759 */ 01760 dm = NULL; 01761 orcodm = NULL; 01762 clothorcodm = NULL; 01763 01764 for(;md; md = md->next, curr = curr->next) { 01765 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 01766 01767 md->scene= scene; 01768 01769 if(!modifier_isEnabled(scene, md, required_mode)) continue; 01770 if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue; 01771 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { 01772 modifier_setError(md, "Modifier requires original data, bad stack position."); 01773 continue; 01774 } 01775 if(sculpt_mode && (!has_multires || multires_applied)) { 01776 int unsupported= 0; 01777 01778 if(scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM) 01779 unsupported|= mti->type != eModifierTypeType_OnlyDeform; 01780 01781 unsupported|= md->type == eModifierType_Multires && ((MultiresModifierData*)md)->sculptlvl==0; 01782 unsupported|= multires_applied; 01783 01784 if(unsupported) { 01785 modifier_setError(md, "Not supported in sculpt mode."); 01786 continue; 01787 } 01788 } 01789 if(needMapping && !modifier_supportsMapping(md)) continue; 01790 if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; 01791 01792 /* add an orco layer if needed by this modifier */ 01793 if(mti->requiredDataMask) 01794 mask = mti->requiredDataMask(ob, md); 01795 else 01796 mask = 0; 01797 01798 if(dm && (mask & CD_MASK_ORCO)) 01799 add_orco_dm(ob, NULL, dm, orcodm, CD_ORCO); 01800 01801 /* How to apply modifier depends on (a) what we already have as 01802 * a result of previous modifiers (could be a DerivedMesh or just 01803 * deformed vertices) and (b) what type the modifier is. 01804 */ 01805 01806 if(mti->type == eModifierTypeType_OnlyDeform) { 01807 /* No existing verts to deform, need to build them. */ 01808 if(!deformedVerts) { 01809 if(dm) { 01810 /* Deforming a derived mesh, read the vertex locations 01811 * out of the mesh and deform them. Once done with this 01812 * run of deformers verts will be written back. 01813 */ 01814 numVerts = dm->getNumVerts(dm); 01815 deformedVerts = 01816 MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv"); 01817 dm->getVertCos(dm, deformedVerts); 01818 } else { 01819 deformedVerts = mesh_getVertexCos(me, &numVerts); 01820 } 01821 } 01822 01823 /* if this is not the last modifier in the stack then recalculate the normals 01824 * to avoid giving bogus normals to the next modifier see: [#23673] */ 01825 if(isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { 01826 /* XXX, this covers bug #23673, but we may need normal calc for other types */ 01827 if(dm && dm->type == DM_TYPE_CDDM) { 01828 CDDM_apply_vert_coords(dm, deformedVerts); 01829 CDDM_calc_normals(dm); 01830 } 01831 } 01832 01833 mti->deformVerts(md, ob, dm, deformedVerts, numVerts, useRenderParams, useDeform); 01834 } else { 01835 DerivedMesh *ndm; 01836 01837 /* determine which data layers are needed by following modifiers */ 01838 if(curr->next) 01839 nextmask= (CustomDataMask)GET_INT_FROM_POINTER(curr->next->link); 01840 else 01841 nextmask= dataMask; 01842 01843 /* apply vertex coordinates or build a DerivedMesh as necessary */ 01844 if(dm) { 01845 if(deformedVerts) { 01846 DerivedMesh *tdm = CDDM_copy(dm); 01847 dm->release(dm); 01848 dm = tdm; 01849 01850 CDDM_apply_vert_coords(dm, deformedVerts); 01851 CDDM_calc_normals(dm); 01852 } 01853 } else { 01854 dm = CDDM_from_mesh(me, ob); 01855 01856 if(deformedVerts) { 01857 CDDM_apply_vert_coords(dm, deformedVerts); 01858 CDDM_calc_normals(dm); 01859 } 01860 01861 if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) 01862 add_weight_mcol_dm(ob, dm); 01863 01864 /* Constructive modifiers need to have an origindex 01865 * otherwise they wont have anywhere to copy the data from. 01866 * 01867 * Also create ORIGINDEX data if any of the following modifiers 01868 * requests it, this way Mirror, Solidify etc will keep ORIGINDEX 01869 * data by using generic DM_copy_vert_data() functions. 01870 */ 01871 if(needMapping || (nextmask & CD_MASK_ORIGINDEX)) { 01872 /* calc */ 01873 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); 01874 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); 01875 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); 01876 01877 range_vni(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); 01878 range_vni(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); 01879 range_vni(DM_get_face_data_layer(dm, CD_ORIGINDEX), dm->numFaceData, 0); 01880 } 01881 } 01882 01883 01884 /* set the DerivedMesh to only copy needed data */ 01885 mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); 01886 /* needMapping check here fixes bug [#28112], otherwise its 01887 * possible that it wont be copied */ 01888 DM_set_only_copy(dm, mask | (needMapping ? CD_MASK_ORIGINDEX : 0)); 01889 01890 /* add cloth rest shape key if need */ 01891 if(mask & CD_MASK_CLOTH_ORCO) 01892 add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO); 01893 01894 /* add an origspace layer if needed */ 01895 if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE) 01896 if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) 01897 DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); 01898 01899 ndm = mti->applyModifier(md, ob, dm, useRenderParams, useCache); 01900 01901 if(ndm) { 01902 /* if the modifier returned a new dm, release the old one */ 01903 if(dm && dm != ndm) dm->release(dm); 01904 01905 dm = ndm; 01906 01907 if(deformedVerts) { 01908 if(deformedVerts != inputVertexCos) 01909 MEM_freeN(deformedVerts); 01910 01911 deformedVerts = NULL; 01912 } 01913 } 01914 01915 /* create an orco derivedmesh in parallel */ 01916 if(nextmask & CD_MASK_ORCO) { 01917 if(!orcodm) 01918 orcodm= create_orco_dm(ob, me, NULL, CD_ORCO); 01919 01920 nextmask &= ~CD_MASK_ORCO; 01921 DM_set_only_copy(orcodm, nextmask | CD_MASK_ORIGINDEX); 01922 ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0); 01923 01924 if(ndm) { 01925 /* if the modifier returned a new dm, release the old one */ 01926 if(orcodm && orcodm != ndm) orcodm->release(orcodm); 01927 orcodm = ndm; 01928 } 01929 } 01930 01931 /* create cloth orco derivedmesh in parallel */ 01932 if(nextmask & CD_MASK_CLOTH_ORCO) { 01933 if(!clothorcodm) 01934 clothorcodm= create_orco_dm(ob, me, NULL, CD_CLOTH_ORCO); 01935 01936 nextmask &= ~CD_MASK_CLOTH_ORCO; 01937 DM_set_only_copy(clothorcodm, nextmask | CD_MASK_ORIGINDEX); 01938 ndm = mti->applyModifier(md, ob, clothorcodm, useRenderParams, 0); 01939 01940 if(ndm) { 01941 /* if the modifier returned a new dm, release the old one */ 01942 if(clothorcodm && clothorcodm != ndm) clothorcodm->release(clothorcodm); 01943 clothorcodm = ndm; 01944 } 01945 } 01946 } 01947 01948 isPrevDeform= (mti->type == eModifierTypeType_OnlyDeform); 01949 01950 /* grab modifiers until index i */ 01951 if((index >= 0) && (modifiers_indexInObject(ob, md) >= index)) 01952 break; 01953 01954 if(sculpt_mode && md->type == eModifierType_Multires) 01955 multires_applied = 1; 01956 } 01957 01958 for(md=firstmd; md; md=md->next) 01959 modifier_freeTemporaryData(md); 01960 01961 /* Yay, we are done. If we have a DerivedMesh and deformed vertices 01962 * need to apply these back onto the DerivedMesh. If we have no 01963 * DerivedMesh then we need to build one. 01964 */ 01965 if(dm && deformedVerts) { 01966 finaldm = CDDM_copy(dm); 01967 01968 dm->release(dm); 01969 01970 CDDM_apply_vert_coords(finaldm, deformedVerts); 01971 CDDM_calc_normals(finaldm); 01972 01973 if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) 01974 add_weight_mcol_dm(ob, finaldm); 01975 } else if(dm) { 01976 finaldm = dm; 01977 } else { 01978 finaldm = CDDM_from_mesh(me, ob); 01979 01980 if(deformedVerts) { 01981 CDDM_apply_vert_coords(finaldm, deformedVerts); 01982 CDDM_calc_normals(finaldm); 01983 } 01984 01985 if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) 01986 add_weight_mcol_dm(ob, finaldm); 01987 } 01988 01989 /* add an orco layer if needed */ 01990 if(dataMask & CD_MASK_ORCO) { 01991 add_orco_dm(ob, NULL, finaldm, orcodm, CD_ORCO); 01992 01993 if(deform_r && *deform_r) 01994 add_orco_dm(ob, NULL, *deform_r, NULL, CD_ORCO); 01995 } 01996 01997 *final_r = finaldm; 01998 01999 if(orcodm) 02000 orcodm->release(orcodm); 02001 if(clothorcodm) 02002 clothorcodm->release(clothorcodm); 02003 02004 if(deformedVerts && deformedVerts != inputVertexCos) 02005 MEM_freeN(deformedVerts); 02006 02007 BLI_linklist_free(datamasks, NULL); 02008 } 02009 02010 float (*editmesh_get_vertex_cos(EditMesh *em, int *numVerts_r))[3] 02011 { 02012 int i, numVerts = *numVerts_r = BLI_countlist(&em->verts); 02013 float (*cos)[3]; 02014 EditVert *eve; 02015 02016 cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos"); 02017 for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) { 02018 VECCOPY(cos[i], eve->co); 02019 } 02020 02021 return cos; 02022 } 02023 02024 int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm) 02025 { 02026 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 02027 int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; 02028 02029 if(!modifier_isEnabled(scene, md, required_mode)) return 0; 02030 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { 02031 modifier_setError(md, "Modifier requires original data, bad stack position."); 02032 return 0; 02033 } 02034 02035 return 1; 02036 } 02037 02038 static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, DerivedMesh **cage_r, 02039 DerivedMesh **final_r, 02040 CustomDataMask dataMask) 02041 { 02042 ModifierData *md; 02043 float (*deformedVerts)[3] = NULL; 02044 CustomDataMask mask; 02045 DerivedMesh *dm, *orcodm = NULL; 02046 int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1); 02047 LinkNode *datamasks, *curr; 02048 int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; 02049 02050 modifiers_clearErrors(ob); 02051 02052 if(cage_r && cageIndex == -1) { 02053 *cage_r = editmesh_get_derived(em, NULL); 02054 } 02055 02056 dm = NULL; 02057 md = modifiers_getVirtualModifierList(ob); 02058 02059 datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); 02060 02061 curr = datamasks; 02062 for(i = 0; md; i++, md = md->next, curr = curr->next) { 02063 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 02064 02065 md->scene= scene; 02066 02067 if(!editmesh_modifier_is_enabled(scene, md, dm)) 02068 continue; 02069 02070 /* add an orco layer if needed by this modifier */ 02071 if(dm && mti->requiredDataMask) { 02072 mask = mti->requiredDataMask(ob, md); 02073 if(mask & CD_MASK_ORCO) 02074 add_orco_dm(ob, em, dm, orcodm, CD_ORCO); 02075 } 02076 02077 /* How to apply modifier depends on (a) what we already have as 02078 * a result of previous modifiers (could be a DerivedMesh or just 02079 * deformed vertices) and (b) what type the modifier is. 02080 */ 02081 02082 if(mti->type == eModifierTypeType_OnlyDeform) { 02083 /* No existing verts to deform, need to build them. */ 02084 if(!deformedVerts) { 02085 if(dm) { 02086 /* Deforming a derived mesh, read the vertex locations 02087 * out of the mesh and deform them. Once done with this 02088 * run of deformers verts will be written back. 02089 */ 02090 numVerts = dm->getNumVerts(dm); 02091 deformedVerts = 02092 MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv"); 02093 dm->getVertCos(dm, deformedVerts); 02094 } else { 02095 deformedVerts = editmesh_get_vertex_cos(em, &numVerts); 02096 } 02097 } 02098 02099 if (mti->deformVertsEM) 02100 mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts); 02101 else mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0, 0); 02102 } else { 02103 DerivedMesh *ndm; 02104 02105 /* apply vertex coordinates or build a DerivedMesh as necessary */ 02106 if(dm) { 02107 if(deformedVerts) { 02108 DerivedMesh *tdm = CDDM_copy(dm); 02109 if(!(cage_r && dm == *cage_r)) dm->release(dm); 02110 dm = tdm; 02111 02112 CDDM_apply_vert_coords(dm, deformedVerts); 02113 CDDM_calc_normals(dm); 02114 } else if(cage_r && dm == *cage_r) { 02115 /* dm may be changed by this modifier, so we need to copy it 02116 */ 02117 dm = CDDM_copy(dm); 02118 } 02119 02120 } else { 02121 dm = CDDM_from_editmesh(em, ob->data); 02122 02123 if(deformedVerts) { 02124 CDDM_apply_vert_coords(dm, deformedVerts); 02125 CDDM_calc_normals(dm); 02126 } 02127 } 02128 02129 /* create an orco derivedmesh in parallel */ 02130 mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); 02131 if(mask & CD_MASK_ORCO) { 02132 if(!orcodm) 02133 orcodm= create_orco_dm(ob, ob->data, em, CD_ORCO); 02134 02135 mask &= ~CD_MASK_ORCO; 02136 DM_set_only_copy(orcodm, mask | CD_MASK_ORIGINDEX); 02137 02138 if (mti->applyModifierEM) 02139 ndm = mti->applyModifierEM(md, ob, em, orcodm); 02140 else 02141 ndm = mti->applyModifier(md, ob, orcodm, 0, 0); 02142 02143 if(ndm) { 02144 /* if the modifier returned a new dm, release the old one */ 02145 if(orcodm && orcodm != ndm) orcodm->release(orcodm); 02146 orcodm = ndm; 02147 } 02148 } 02149 02150 /* set the DerivedMesh to only copy needed data */ 02151 mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); /* CD_MASK_ORCO may have been cleared above */ 02152 02153 DM_set_only_copy(dm, mask | CD_MASK_ORIGINDEX); 02154 02155 if(mask & CD_MASK_ORIGSPACE) 02156 if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) 02157 DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); 02158 02159 if (mti->applyModifierEM) 02160 ndm = mti->applyModifierEM(md, ob, em, dm); 02161 else 02162 ndm = mti->applyModifier(md, ob, dm, 0, 0); 02163 02164 if (ndm) { 02165 if(dm && dm != ndm) 02166 dm->release(dm); 02167 02168 dm = ndm; 02169 02170 if (deformedVerts) { 02171 MEM_freeN(deformedVerts); 02172 deformedVerts = NULL; 02173 } 02174 } 02175 } 02176 02177 if(cage_r && i == cageIndex) { 02178 if(dm && deformedVerts) { 02179 *cage_r = CDDM_copy(dm); 02180 CDDM_apply_vert_coords(*cage_r, deformedVerts); 02181 } else if(dm) { 02182 *cage_r = dm; 02183 } else { 02184 *cage_r = 02185 editmesh_get_derived(em, 02186 deformedVerts ? MEM_dupallocN(deformedVerts) : NULL); 02187 } 02188 } 02189 } 02190 02191 BLI_linklist_free(datamasks, NULL); 02192 02193 /* Yay, we are done. If we have a DerivedMesh and deformed vertices need 02194 * to apply these back onto the DerivedMesh. If we have no DerivedMesh 02195 * then we need to build one. 02196 */ 02197 if(dm && deformedVerts) { 02198 *final_r = CDDM_copy(dm); 02199 02200 if(!(cage_r && dm == *cage_r)) dm->release(dm); 02201 02202 CDDM_apply_vert_coords(*final_r, deformedVerts); 02203 CDDM_calc_normals(*final_r); 02204 } else if (dm) { 02205 *final_r = dm; 02206 } else if (!deformedVerts && cage_r && *cage_r) { 02207 *final_r = *cage_r; 02208 } else { 02209 *final_r = editmesh_get_derived(em, deformedVerts); 02210 deformedVerts = NULL; 02211 } 02212 02213 /* add an orco layer if needed */ 02214 if(dataMask & CD_MASK_ORCO) 02215 add_orco_dm(ob, em, *final_r, orcodm, CD_ORCO); 02216 02217 if(orcodm) 02218 orcodm->release(orcodm); 02219 02220 if(deformedVerts) 02221 MEM_freeN(deformedVerts); 02222 } 02223 02224 static void clear_mesh_caches(Object *ob) 02225 { 02226 Mesh *me= ob->data; 02227 02228 /* also serves as signal to remake texspace */ 02229 if (ob->bb) { 02230 MEM_freeN(ob->bb); 02231 ob->bb = NULL; 02232 } 02233 if (me->bb) { 02234 MEM_freeN(me->bb); 02235 me->bb = NULL; 02236 } 02237 02238 freedisplist(&ob->disp); 02239 02240 if (ob->derivedFinal) { 02241 ob->derivedFinal->needsFree = 1; 02242 ob->derivedFinal->release(ob->derivedFinal); 02243 ob->derivedFinal= NULL; 02244 } 02245 if (ob->derivedDeform) { 02246 ob->derivedDeform->needsFree = 1; 02247 ob->derivedDeform->release(ob->derivedDeform); 02248 ob->derivedDeform= NULL; 02249 } 02250 02251 if(ob->sculpt) { 02252 ED_sculpt_modifiers_changed(ob); 02253 } 02254 } 02255 02256 static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask) 02257 { 02258 Object *obact = scene->basact?scene->basact->object:NULL; 02259 int editing = paint_facesel_test(ob); 02260 /* weight paint and face select need original indices because of selection buffer drawing */ 02261 int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT))); 02262 02263 clear_mesh_caches(ob); 02264 02265 mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform, 02266 &ob->derivedFinal, 0, 1, 02267 needMapping, dataMask, -1, 1); 02268 02269 DM_set_object_boundbox (ob, ob->derivedFinal); 02270 02271 ob->derivedFinal->needsFree = 0; 02272 ob->derivedDeform->needsFree = 0; 02273 ob->lastDataMask = dataMask; 02274 } 02275 02276 static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask) 02277 { 02278 clear_mesh_caches(obedit); 02279 02280 if (em->derivedFinal) { 02281 if (em->derivedFinal!=em->derivedCage) { 02282 em->derivedFinal->needsFree = 1; 02283 em->derivedFinal->release(em->derivedFinal); 02284 } 02285 em->derivedFinal = NULL; 02286 } 02287 if (em->derivedCage) { 02288 em->derivedCage->needsFree = 1; 02289 em->derivedCage->release(em->derivedCage); 02290 em->derivedCage = NULL; 02291 } 02292 02293 editmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask); 02294 DM_set_object_boundbox (obedit, em->derivedFinal); 02295 02296 em->lastDataMask = dataMask; 02297 em->derivedFinal->needsFree = 0; 02298 em->derivedCage->needsFree = 0; 02299 } 02300 02301 void makeDerivedMesh(Scene *scene, Object *ob, EditMesh *em, CustomDataMask dataMask) 02302 { 02303 if (em) { 02304 editmesh_build_data(scene, ob, em, dataMask); 02305 } else { 02306 mesh_build_data(scene, ob, dataMask); 02307 } 02308 } 02309 02310 /***/ 02311 02312 DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dataMask) 02313 { 02314 /* if there's no derived mesh or the last data mask used doesn't include 02315 * the data we need, rebuild the derived mesh 02316 */ 02317 if(!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask) 02318 mesh_build_data(scene, ob, dataMask); 02319 02320 return ob->derivedFinal; 02321 } 02322 02323 DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask dataMask) 02324 { 02325 /* if there's no derived mesh or the last data mask used doesn't include 02326 * the data we need, rebuild the derived mesh 02327 */ 02328 if(!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask) 02329 mesh_build_data(scene, ob, dataMask); 02330 02331 return ob->derivedDeform; 02332 } 02333 02334 DerivedMesh *mesh_create_derived_render(Scene *scene, Object *ob, CustomDataMask dataMask) 02335 { 02336 DerivedMesh *final; 02337 02338 mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1, 0); 02339 02340 return final; 02341 } 02342 02343 DerivedMesh *mesh_create_derived_index_render(Scene *scene, Object *ob, CustomDataMask dataMask, int index) 02344 { 02345 DerivedMesh *final; 02346 02347 mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, index, 0); 02348 02349 return final; 02350 } 02351 02352 DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask dataMask) 02353 { 02354 DerivedMesh *final; 02355 02356 mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0); 02357 02358 return final; 02359 } 02360 02361 DerivedMesh *mesh_create_derived_no_deform(Scene *scene, Object *ob, float (*vertCos)[3], 02362 CustomDataMask dataMask) 02363 { 02364 DerivedMesh *final; 02365 02366 mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, 0, 0, dataMask, -1, 0); 02367 02368 return final; 02369 } 02370 02371 DerivedMesh *mesh_create_derived_no_virtual(Scene *scene, Object *ob, float (*vertCos)[3], 02372 CustomDataMask dataMask) 02373 { 02374 DerivedMesh *final; 02375 02376 mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1, 0); 02377 02378 return final; 02379 } 02380 02381 DerivedMesh *mesh_create_derived_physics(Scene *scene, Object *ob, float (*vertCos)[3], 02382 CustomDataMask dataMask) 02383 { 02384 DerivedMesh *final; 02385 02386 mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 1, dataMask, -1, 0); 02387 02388 return final; 02389 } 02390 02391 DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob, 02392 float (*vertCos)[3], 02393 CustomDataMask dataMask) 02394 { 02395 DerivedMesh *final; 02396 02397 mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 1, 0, 0, dataMask, -1, 0); 02398 02399 return final; 02400 } 02401 02402 /***/ 02403 02404 DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, EditMesh *em, DerivedMesh **final_r, 02405 CustomDataMask dataMask) 02406 { 02407 /* if there's no derived mesh or the last data mask used doesn't include 02408 * the data we need, rebuild the derived mesh 02409 */ 02410 if(!em->derivedCage || 02411 (em->lastDataMask & dataMask) != dataMask) 02412 editmesh_build_data(scene, obedit, em, dataMask); 02413 02414 *final_r = em->derivedFinal; 02415 return em->derivedCage; 02416 } 02417 02418 DerivedMesh *editmesh_get_derived_cage(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask) 02419 { 02420 /* if there's no derived mesh or the last data mask used doesn't include 02421 * the data we need, rebuild the derived mesh 02422 */ 02423 if(!em->derivedCage || 02424 (em->lastDataMask & dataMask) != dataMask) 02425 editmesh_build_data(scene, obedit, em, dataMask); 02426 02427 return em->derivedCage; 02428 } 02429 02430 DerivedMesh *editmesh_get_derived_base(Object *UNUSED(obedit), EditMesh *em) 02431 { 02432 return editmesh_get_derived(em, NULL); 02433 } 02434 02435 02436 /* ********* For those who don't grasp derived stuff! (ton) :) *************** */ 02437 02438 static void make_vertexcosnos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) 02439 { 02440 float *vec = userData; 02441 02442 vec+= 6*index; 02443 02444 /* check if we've been here before (normal should not be 0) */ 02445 if(vec[3] || vec[4] || vec[5]) return; 02446 02447 VECCOPY(vec, co); 02448 vec+= 3; 02449 if(no_f) { 02450 VECCOPY(vec, no_f); 02451 } 02452 else { 02453 VECCOPY(vec, no_s); 02454 } 02455 } 02456 02457 /* always returns original amount me->totvert of vertices and normals, but fully deformed and subsurfered */ 02458 /* this is needed for all code using vertexgroups (no subsurf support) */ 02459 /* it stores the normals as floats, but they can still be scaled as shorts (32767 = unit) */ 02460 /* in use now by vertex/weight paint and particle generating */ 02461 02462 float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob) 02463 { 02464 Mesh *me= ob->data; 02465 DerivedMesh *dm; 02466 float *vertexcosnos; 02467 02468 /* lets prevent crashing... */ 02469 if(ob->type!=OB_MESH || me->totvert==0) 02470 return NULL; 02471 02472 dm= mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); 02473 vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map"); 02474 02475 if(dm->foreachMappedVert) { 02476 dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos); 02477 } 02478 else { 02479 float *fp= vertexcosnos; 02480 int a; 02481 02482 for(a=0; a< me->totvert; a++, fp+=6) { 02483 dm->getVertCo(dm, a, fp); 02484 dm->getVertNo(dm, a, fp+3); 02485 } 02486 } 02487 02488 dm->release(dm); 02489 return vertexcosnos; 02490 } 02491 02492 /* ******************* GLSL ******************** */ 02493 02494 typedef struct 02495 { 02496 float * precomputedFaceNormals; 02497 MTFace * mtface; // texture coordinates 02498 MFace * mface; // indices 02499 MVert * mvert; // vertices & normals 02500 float (*orco)[3]; 02501 float (*tangent)[4]; // destination 02502 int numFaces; 02503 02504 } SGLSLMeshToTangent; 02505 02506 // interface 02507 #include "mikktspace.h" 02508 02509 static int GetNumFaces(const SMikkTSpaceContext * pContext) 02510 { 02511 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 02512 return pMesh->numFaces; 02513 } 02514 02515 static int GetNumVertsOfFace(const SMikkTSpaceContext * pContext, const int face_num) 02516 { 02517 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 02518 return pMesh->mface[face_num].v4!=0 ? 4 : 3; 02519 } 02520 02521 static void GetPosition(const SMikkTSpaceContext * pContext, float fPos[], const int face_num, const int vert_index) 02522 { 02523 //assert(vert_index>=0 && vert_index<4); 02524 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 02525 const float *co= pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].co; 02526 VECCOPY(fPos, co); 02527 } 02528 02529 static void GetTextureCoordinate(const SMikkTSpaceContext * pContext, float fUV[], const int face_num, const int vert_index) 02530 { 02531 //assert(vert_index>=0 && vert_index<4); 02532 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 02533 02534 if(pMesh->mtface!=NULL) { 02535 float * uv = pMesh->mtface[face_num].uv[vert_index]; 02536 fUV[0]=uv[0]; fUV[1]=uv[1]; 02537 } 02538 else { 02539 const float *orco= pMesh->orco[(&pMesh->mface[face_num].v1)[vert_index]]; 02540 map_to_sphere( &fUV[0], &fUV[1], orco[0], orco[1], orco[2]); 02541 } 02542 } 02543 02544 static void GetNormal(const SMikkTSpaceContext * pContext, float fNorm[], const int face_num, const int vert_index) 02545 { 02546 //assert(vert_index>=0 && vert_index<4); 02547 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 02548 02549 const int smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH); 02550 if(!smoothnormal) { // flat 02551 if(pMesh->precomputedFaceNormals) { 02552 VECCOPY(fNorm, &pMesh->precomputedFaceNormals[3*face_num]); 02553 } 02554 else { 02555 MFace *mf= &pMesh->mface[face_num]; 02556 float *p0= pMesh->mvert[mf->v1].co; 02557 float *p1= pMesh->mvert[mf->v2].co; 02558 float *p2= pMesh->mvert[mf->v3].co; 02559 02560 if(mf->v4) { 02561 float *p3 = pMesh->mvert[mf->v4].co; 02562 normal_quad_v3(fNorm, p0, p1, p2, p3); 02563 } 02564 else { 02565 normal_tri_v3(fNorm, p0, p1, p2); 02566 } 02567 } 02568 } 02569 else { 02570 const short *no= pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].no; 02571 normal_short_to_float_v3(fNorm, no); 02572 } 02573 } 02574 static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int face_num, const int iVert) 02575 { 02576 //assert(vert_index>=0 && vert_index<4); 02577 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 02578 float * pRes = pMesh->tangent[4*face_num+iVert]; 02579 VECCOPY(pRes, fvTangent); 02580 pRes[3]=fSign; 02581 } 02582 02583 02584 void DM_add_tangent_layer(DerivedMesh *dm) 02585 { 02586 /* mesh vars */ 02587 MTFace *mtface, *tf; 02588 MFace *mface, *mf; 02589 MVert *mvert, *v1, *v2, *v3, *v4; 02590 MemArena *arena= NULL; 02591 VertexTangent **vtangents= NULL; 02592 float (*orco)[3]= NULL, (*tangent)[4]; 02593 float *uv1, *uv2, *uv3, *uv4, *vtang; 02594 float fno[3], tang[3], uv[4][2]; 02595 int i, j, len, mf_vi[4], totvert, totface, iCalcNewMethod; 02596 float *nors; 02597 02598 if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1) 02599 return; 02600 02601 nors = dm->getFaceDataArray(dm, CD_NORMAL); 02602 02603 /* check we have all the needed layers */ 02604 totvert= dm->getNumVerts(dm); 02605 totface= dm->getNumFaces(dm); 02606 02607 mvert= dm->getVertArray(dm); 02608 mface= dm->getFaceArray(dm); 02609 mtface= dm->getFaceDataArray(dm, CD_MTFACE); 02610 02611 if(!mtface) { 02612 orco= dm->getVertDataArray(dm, CD_ORCO); 02613 if(!orco) 02614 return; 02615 } 02616 02617 /* create tangent layer */ 02618 DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL); 02619 tangent= DM_get_face_data_layer(dm, CD_TANGENT); 02620 02621 /* allocate some space */ 02622 arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "tangent layer arena"); 02623 BLI_memarena_use_calloc(arena); 02624 vtangents= MEM_callocN(sizeof(VertexTangent*)*totvert, "VertexTangent"); 02625 02626 // new computation method 02627 iCalcNewMethod = 1; 02628 if(iCalcNewMethod != 0) { 02629 SGLSLMeshToTangent mesh2tangent= {0}; 02630 SMikkTSpaceContext sContext= {0}; 02631 SMikkTSpaceInterface sInterface= {0}; 02632 02633 mesh2tangent.precomputedFaceNormals = nors; 02634 mesh2tangent.mtface = mtface; 02635 mesh2tangent.mface = mface; 02636 mesh2tangent.mvert = mvert; 02637 mesh2tangent.orco = orco; 02638 mesh2tangent.tangent = tangent; 02639 mesh2tangent.numFaces = totface; 02640 02641 sContext.m_pUserData = &mesh2tangent; 02642 sContext.m_pInterface = &sInterface; 02643 sInterface.m_getNumFaces = GetNumFaces; 02644 sInterface.m_getNumVerticesOfFace = GetNumVertsOfFace; 02645 sInterface.m_getPosition = GetPosition; 02646 sInterface.m_getTexCoord = GetTextureCoordinate; 02647 sInterface.m_getNormal = GetNormal; 02648 sInterface.m_setTSpaceBasic = SetTSpace; 02649 02650 // 0 if failed 02651 iCalcNewMethod = genTangSpaceDefault(&sContext); 02652 } 02653 02654 if(!iCalcNewMethod) { 02655 /* sum tangents at connected vertices */ 02656 for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) { 02657 v1= &mvert[mf->v1]; 02658 v2= &mvert[mf->v2]; 02659 v3= &mvert[mf->v3]; 02660 02661 if (mf->v4) { 02662 v4= &mvert[mf->v4]; 02663 normal_quad_v3( fno,v4->co, v3->co, v2->co, v1->co); 02664 } 02665 else { 02666 v4= NULL; 02667 normal_tri_v3( fno,v3->co, v2->co, v1->co); 02668 } 02669 02670 if(mtface) { 02671 uv1= tf->uv[0]; 02672 uv2= tf->uv[1]; 02673 uv3= tf->uv[2]; 02674 uv4= tf->uv[3]; 02675 } 02676 else { 02677 uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3]; 02678 map_to_sphere( &uv[0][0], &uv[0][1],orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2]); 02679 map_to_sphere( &uv[1][0], &uv[1][1],orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2]); 02680 map_to_sphere( &uv[2][0], &uv[2][1],orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2]); 02681 if(v4) 02682 map_to_sphere( &uv[3][0], &uv[3][1],orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2]); 02683 } 02684 02685 tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang); 02686 sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); 02687 sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2); 02688 sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); 02689 02690 if(mf->v4) { 02691 v4= &mvert[mf->v4]; 02692 02693 tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang); 02694 sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); 02695 sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); 02696 sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4); 02697 } 02698 } 02699 02700 /* write tangent to layer */ 02701 for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++, tangent+=4) { 02702 len= (mf->v4)? 4 : 3; 02703 02704 if(mtface == NULL) { 02705 map_to_sphere( &uv[0][0], &uv[0][1],orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2]); 02706 map_to_sphere( &uv[1][0], &uv[1][1],orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2]); 02707 map_to_sphere( &uv[2][0], &uv[2][1],orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2]); 02708 if(len==4) 02709 map_to_sphere( &uv[3][0], &uv[3][1],orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2]); 02710 } 02711 02712 mf_vi[0]= mf->v1; 02713 mf_vi[1]= mf->v2; 02714 mf_vi[2]= mf->v3; 02715 mf_vi[3]= mf->v4; 02716 02717 for(j=0; j<len; j++) { 02718 vtang= find_vertex_tangent(vtangents[mf_vi[j]], mtface ? tf->uv[j] : uv[j]); 02719 normalize_v3_v3(tangent[j], vtang); 02720 ((float *) tangent[j])[3]=1.0f; 02721 } 02722 } 02723 } 02724 02725 BLI_memarena_free(arena); 02726 MEM_freeN(vtangents); 02727 } 02728 02729 void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs) 02730 { 02731 CustomData *vdata, *fdata, *tfdata = NULL; 02732 int a, b, layer; 02733 02734 /* From the layers requested by the GLSL shader, figure out which ones are 02735 * actually available for this derivedmesh, and retrieve the pointers */ 02736 02737 memset(attribs, 0, sizeof(DMVertexAttribs)); 02738 02739 vdata = &dm->vertData; 02740 fdata = &dm->faceData; 02741 02742 /* ugly hack, editmesh derivedmesh doesn't copy face data, this way we 02743 * can use offsets instead */ 02744 if(dm->release == emDM_release) 02745 tfdata = &((EditMeshDerivedMesh*)dm)->em->fdata; 02746 else 02747 tfdata = fdata; 02748 02749 /* add a tangent layer if necessary */ 02750 for(b = 0; b < gattribs->totlayer; b++) 02751 if(gattribs->layer[b].type == CD_TANGENT) 02752 if(CustomData_get_layer_index(fdata, CD_TANGENT) == -1) 02753 DM_add_tangent_layer(dm); 02754 02755 for(b = 0; b < gattribs->totlayer; b++) { 02756 if(gattribs->layer[b].type == CD_MTFACE) { 02757 /* uv coordinates */ 02758 if(gattribs->layer[b].name[0]) 02759 layer = CustomData_get_named_layer_index(tfdata, CD_MTFACE, 02760 gattribs->layer[b].name); 02761 else 02762 layer = CustomData_get_active_layer_index(tfdata, CD_MTFACE); 02763 02764 if(layer != -1) { 02765 a = attribs->tottface++; 02766 02767 attribs->tface[a].array = tfdata->layers[layer].data; 02768 attribs->tface[a].emOffset = tfdata->layers[layer].offset; 02769 attribs->tface[a].glIndex = gattribs->layer[b].glindex; 02770 } 02771 } 02772 else if(gattribs->layer[b].type == CD_MCOL) { 02773 /* vertex colors */ 02774 if(gattribs->layer[b].name[0]) 02775 layer = CustomData_get_named_layer_index(tfdata, CD_MCOL, 02776 gattribs->layer[b].name); 02777 else 02778 layer = CustomData_get_active_layer_index(tfdata, CD_MCOL); 02779 02780 if(layer != -1) { 02781 a = attribs->totmcol++; 02782 02783 attribs->mcol[a].array = tfdata->layers[layer].data; 02784 attribs->mcol[a].emOffset = tfdata->layers[layer].offset; 02785 attribs->mcol[a].glIndex = gattribs->layer[b].glindex; 02786 } 02787 } 02788 else if(gattribs->layer[b].type == CD_TANGENT) { 02789 /* tangents */ 02790 layer = CustomData_get_layer_index(fdata, CD_TANGENT); 02791 02792 if(layer != -1) { 02793 attribs->tottang = 1; 02794 02795 attribs->tang.array = fdata->layers[layer].data; 02796 attribs->tang.emOffset = fdata->layers[layer].offset; 02797 attribs->tang.glIndex = gattribs->layer[b].glindex; 02798 } 02799 } 02800 else if(gattribs->layer[b].type == CD_ORCO) { 02801 /* original coordinates */ 02802 layer = CustomData_get_layer_index(vdata, CD_ORCO); 02803 02804 if(layer != -1) { 02805 attribs->totorco = 1; 02806 02807 attribs->orco.array = vdata->layers[layer].data; 02808 attribs->orco.emOffset = vdata->layers[layer].offset; 02809 attribs->orco.glIndex = gattribs->layer[b].glindex; 02810 } 02811 } 02812 } 02813 } 02814 02815 /* Set object's bounding box based on DerivedMesh min/max data */ 02816 void DM_set_object_boundbox(Object *ob, DerivedMesh *dm) 02817 { 02818 float min[3], max[3]; 02819 02820 INIT_MINMAX(min, max); 02821 02822 dm->getMinMax(dm, min, max); 02823 02824 if(!ob->bb) 02825 ob->bb= MEM_callocN(sizeof(BoundBox), "bb"); 02826 02827 boundbox_set_from_min_max(ob->bb, min, max); 02828 }