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 <string.h> 00034 00035 00036 #include "MEM_guardedalloc.h" 00037 00038 #include "DNA_cloth_types.h" 00039 #include "DNA_key_types.h" 00040 #include "DNA_meshdata_types.h" 00041 #include "DNA_armature_types.h" 00042 #include "DNA_object_types.h" 00043 #include "DNA_scene_types.h" // N_T 00044 00045 #include "BLI_blenlib.h" 00046 #include "BLI_editVert.h" 00047 #include "BLI_math.h" 00048 #include "BLI_memarena.h" 00049 #include "BLI_pbvh.h" 00050 #include "BLI_utildefines.h" 00051 #include "BLI_linklist.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 #include "BKE_armature.h" 00063 #include "BKE_deform.h" 00064 00065 #ifdef WITH_GAMEENGINE 00066 #include "BKE_navmesh_conversion.h" 00067 static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm); 00068 #endif 00069 00070 #include "BLO_sys_types.h" // for intptr_t support 00071 00072 #include "GL/glew.h" 00073 00074 #include "GPU_buffers.h" 00075 #include "GPU_draw.h" 00076 #include "GPU_extensions.h" 00077 #include "GPU_material.h" 00078 00079 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */ 00080 00083 00084 static MVert *dm_getVertArray(DerivedMesh *dm) 00085 { 00086 MVert *mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); 00087 00088 if (!mvert) { 00089 mvert = CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, 00090 dm->getNumVerts(dm)); 00091 CustomData_set_layer_flag(&dm->vertData, CD_MVERT, CD_FLAG_TEMPORARY); 00092 dm->copyVertArray(dm, mvert); 00093 } 00094 00095 return mvert; 00096 } 00097 00098 static MEdge *dm_getEdgeArray(DerivedMesh *dm) 00099 { 00100 MEdge *medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); 00101 00102 if (!medge) { 00103 medge = CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, 00104 dm->getNumEdges(dm)); 00105 CustomData_set_layer_flag(&dm->edgeData, CD_MEDGE, CD_FLAG_TEMPORARY); 00106 dm->copyEdgeArray(dm, medge); 00107 } 00108 00109 return medge; 00110 } 00111 00112 static MFace *dm_getFaceArray(DerivedMesh *dm) 00113 { 00114 MFace *mface = CustomData_get_layer(&dm->faceData, CD_MFACE); 00115 00116 if (!mface) { 00117 mface = CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, 00118 dm->getNumFaces(dm)); 00119 CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY); 00120 dm->copyFaceArray(dm, mface); 00121 } 00122 00123 return mface; 00124 } 00125 00126 static MVert *dm_dupVertArray(DerivedMesh *dm) 00127 { 00128 MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm), 00129 "dm_dupVertArray tmp"); 00130 00131 if(tmp) dm->copyVertArray(dm, tmp); 00132 00133 return tmp; 00134 } 00135 00136 static MEdge *dm_dupEdgeArray(DerivedMesh *dm) 00137 { 00138 MEdge *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumEdges(dm), 00139 "dm_dupEdgeArray tmp"); 00140 00141 if(tmp) dm->copyEdgeArray(dm, tmp); 00142 00143 return tmp; 00144 } 00145 00146 static MFace *dm_dupFaceArray(DerivedMesh *dm) 00147 { 00148 MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumFaces(dm), 00149 "dm_dupFaceArray tmp"); 00150 00151 if(tmp) dm->copyFaceArray(dm, tmp); 00152 00153 return tmp; 00154 } 00155 00156 void DM_init_funcs(DerivedMesh *dm) 00157 { 00158 /* default function implementations */ 00159 dm->getVertArray = dm_getVertArray; 00160 dm->getEdgeArray = dm_getEdgeArray; 00161 dm->getFaceArray = dm_getFaceArray; 00162 dm->dupVertArray = dm_dupVertArray; 00163 dm->dupEdgeArray = dm_dupEdgeArray; 00164 dm->dupFaceArray = dm_dupFaceArray; 00165 00166 dm->getVertData = DM_get_vert_data; 00167 dm->getEdgeData = DM_get_edge_data; 00168 dm->getFaceData = DM_get_face_data; 00169 dm->getVertDataArray = DM_get_vert_data_layer; 00170 dm->getEdgeDataArray = DM_get_edge_data_layer; 00171 dm->getFaceDataArray = DM_get_face_data_layer; 00172 00173 bvhcache_init(&dm->bvhCache); 00174 } 00175 00176 void DM_init(DerivedMesh *dm, DerivedMeshType type, 00177 int numVerts, int numEdges, int numFaces) 00178 { 00179 dm->type = type; 00180 dm->numVertData = numVerts; 00181 dm->numEdgeData = numEdges; 00182 dm->numFaceData = numFaces; 00183 00184 DM_init_funcs(dm); 00185 00186 dm->needsFree = 1; 00187 dm->auto_bump_scale = -1.0f; 00188 } 00189 00190 void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, 00191 int numVerts, int numEdges, int numFaces) 00192 { 00193 CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH, 00194 CD_CALLOC, numVerts); 00195 CustomData_copy(&source->edgeData, &dm->edgeData, CD_MASK_DERIVEDMESH, 00196 CD_CALLOC, numEdges); 00197 CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH, 00198 CD_CALLOC, numFaces); 00199 00200 dm->type = type; 00201 dm->numVertData = numVerts; 00202 dm->numEdgeData = numEdges; 00203 dm->numFaceData = numFaces; 00204 00205 DM_init_funcs(dm); 00206 00207 dm->needsFree = 1; 00208 } 00209 00210 int DM_release(DerivedMesh *dm) 00211 { 00212 if (dm->needsFree) { 00213 bvhcache_free(&dm->bvhCache); 00214 GPU_drawobject_free( dm ); 00215 CustomData_free(&dm->vertData, dm->numVertData); 00216 CustomData_free(&dm->edgeData, dm->numEdgeData); 00217 CustomData_free(&dm->faceData, dm->numFaceData); 00218 00219 return 1; 00220 } 00221 else { 00222 CustomData_free_temporary(&dm->vertData, dm->numVertData); 00223 CustomData_free_temporary(&dm->edgeData, dm->numEdgeData); 00224 CustomData_free_temporary(&dm->faceData, dm->numFaceData); 00225 00226 return 0; 00227 } 00228 } 00229 00230 void DM_to_mesh(DerivedMesh *dm, Mesh *me) 00231 { 00232 /* dm might depend on me, so we need to do everything with a local copy */ 00233 Mesh tmp = *me; 00234 int totvert, totedge, totface; 00235 00236 memset(&tmp.vdata, 0, sizeof(tmp.vdata)); 00237 memset(&tmp.edata, 0, sizeof(tmp.edata)); 00238 memset(&tmp.fdata, 0, sizeof(tmp.fdata)); 00239 00240 totvert = tmp.totvert = dm->getNumVerts(dm); 00241 totedge = tmp.totedge = dm->getNumEdges(dm); 00242 totface = tmp.totface = dm->getNumFaces(dm); 00243 00244 CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert); 00245 CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge); 00246 CustomData_copy(&dm->faceData, &tmp.fdata, CD_MASK_MESH, CD_DUPLICATE, totface); 00247 00248 /* not all DerivedMeshes store their verts/edges/faces in CustomData, so 00249 we set them here in case they are missing */ 00250 if(!CustomData_has_layer(&tmp.vdata, CD_MVERT)) 00251 CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, dm->dupVertArray(dm), totvert); 00252 if(!CustomData_has_layer(&tmp.edata, CD_MEDGE)) 00253 CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge); 00254 if(!CustomData_has_layer(&tmp.fdata, CD_MFACE)) 00255 CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface); 00256 00257 /* object had got displacement layer, should copy this layer to save sculpted data */ 00258 /* NOTE: maybe some other layers should be copied? nazgul */ 00259 if(CustomData_has_layer(&me->fdata, CD_MDISPS)) { 00260 if (totface == me->totface) { 00261 MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS); 00262 CustomData_add_layer(&tmp.fdata, CD_MDISPS, CD_DUPLICATE, mdisps, totface); 00263 } 00264 } 00265 00266 mesh_update_customdata_pointers(&tmp); 00267 00268 CustomData_free(&me->vdata, me->totvert); 00269 CustomData_free(&me->edata, me->totedge); 00270 CustomData_free(&me->fdata, me->totface); 00271 00272 /* if the number of verts has changed, remove invalid data */ 00273 if(tmp.totvert != me->totvert) { 00274 if(tmp.key) tmp.key->id.us--; 00275 tmp.key = NULL; 00276 } 00277 00278 *me = tmp; 00279 } 00280 00281 void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb) 00282 { 00283 int a, totvert = dm->getNumVerts(dm); 00284 float *fp; 00285 MVert *mvert; 00286 00287 if(totvert==0 || me->totvert==0 || me->totvert!=totvert) return; 00288 00289 if(kb->data) MEM_freeN(kb->data); 00290 kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data"); 00291 kb->totelem= totvert; 00292 00293 fp= kb->data; 00294 mvert=dm->getVertDataArray(dm, CD_MVERT); 00295 00296 for(a=0; a<kb->totelem; a++, fp+=3, mvert++) { 00297 copy_v3_v3(fp, mvert->co); 00298 } 00299 } 00300 00301 void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask) 00302 { 00303 CustomData_set_only_copy(&dm->vertData, mask); 00304 CustomData_set_only_copy(&dm->edgeData, mask); 00305 CustomData_set_only_copy(&dm->faceData, mask); 00306 } 00307 00308 void DM_add_vert_layer(DerivedMesh *dm, int type, int alloctype, void *layer) 00309 { 00310 CustomData_add_layer(&dm->vertData, type, alloctype, layer, dm->numVertData); 00311 } 00312 00313 void DM_add_edge_layer(DerivedMesh *dm, int type, int alloctype, void *layer) 00314 { 00315 CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData); 00316 } 00317 00318 void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer) 00319 { 00320 CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numFaceData); 00321 } 00322 00323 void *DM_get_vert_data(DerivedMesh *dm, int index, int type) 00324 { 00325 return CustomData_get(&dm->vertData, index, type); 00326 } 00327 00328 void *DM_get_edge_data(DerivedMesh *dm, int index, int type) 00329 { 00330 return CustomData_get(&dm->edgeData, index, type); 00331 } 00332 00333 void *DM_get_face_data(DerivedMesh *dm, int index, int type) 00334 { 00335 return CustomData_get(&dm->faceData, index, type); 00336 } 00337 00338 void *DM_get_vert_data_layer(DerivedMesh *dm, int type) 00339 { 00340 if(type == CD_MVERT) 00341 return dm->getVertArray(dm); 00342 00343 return CustomData_get_layer(&dm->vertData, type); 00344 } 00345 00346 void *DM_get_edge_data_layer(DerivedMesh *dm, int type) 00347 { 00348 if(type == CD_MEDGE) 00349 return dm->getEdgeArray(dm); 00350 00351 return CustomData_get_layer(&dm->edgeData, type); 00352 } 00353 00354 void *DM_get_face_data_layer(DerivedMesh *dm, int type) 00355 { 00356 if(type == CD_MFACE) 00357 return dm->getFaceArray(dm); 00358 00359 return CustomData_get_layer(&dm->faceData, type); 00360 } 00361 00362 void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data) 00363 { 00364 CustomData_set(&dm->vertData, index, type, data); 00365 } 00366 00367 void DM_set_edge_data(DerivedMesh *dm, int index, int type, void *data) 00368 { 00369 CustomData_set(&dm->edgeData, index, type, data); 00370 } 00371 00372 void DM_set_face_data(DerivedMesh *dm, int index, int type, void *data) 00373 { 00374 CustomData_set(&dm->faceData, index, type, data); 00375 } 00376 00377 void DM_copy_vert_data(DerivedMesh *source, DerivedMesh *dest, 00378 int source_index, int dest_index, int count) 00379 { 00380 CustomData_copy_data(&source->vertData, &dest->vertData, 00381 source_index, dest_index, count); 00382 } 00383 00384 void DM_copy_edge_data(DerivedMesh *source, DerivedMesh *dest, 00385 int source_index, int dest_index, int count) 00386 { 00387 CustomData_copy_data(&source->edgeData, &dest->edgeData, 00388 source_index, dest_index, count); 00389 } 00390 00391 void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest, 00392 int source_index, int dest_index, int count) 00393 { 00394 CustomData_copy_data(&source->faceData, &dest->faceData, 00395 source_index, dest_index, count); 00396 } 00397 00398 void DM_free_vert_data(struct DerivedMesh *dm, int index, int count) 00399 { 00400 CustomData_free_elem(&dm->vertData, index, count); 00401 } 00402 00403 void DM_free_edge_data(struct DerivedMesh *dm, int index, int count) 00404 { 00405 CustomData_free_elem(&dm->edgeData, index, count); 00406 } 00407 00408 void DM_free_face_data(struct DerivedMesh *dm, int index, int count) 00409 { 00410 CustomData_free_elem(&dm->faceData, index, count); 00411 } 00412 00413 void DM_interp_vert_data(DerivedMesh *source, DerivedMesh *dest, 00414 int *src_indices, float *weights, 00415 int count, int dest_index) 00416 { 00417 CustomData_interp(&source->vertData, &dest->vertData, src_indices, 00418 weights, NULL, count, dest_index); 00419 } 00420 00421 void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest, 00422 int *src_indices, 00423 float *weights, EdgeVertWeight *vert_weights, 00424 int count, int dest_index) 00425 { 00426 CustomData_interp(&source->edgeData, &dest->edgeData, src_indices, 00427 weights, (float*)vert_weights, count, dest_index); 00428 } 00429 00430 void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest, 00431 int *src_indices, 00432 float *weights, FaceVertWeight *vert_weights, 00433 int count, int dest_index) 00434 { 00435 CustomData_interp(&source->faceData, &dest->faceData, src_indices, 00436 weights, (float*)vert_weights, count, dest_index); 00437 } 00438 00439 void DM_swap_face_data(DerivedMesh *dm, int index, const int *corner_indices) 00440 { 00441 CustomData_swap(&dm->faceData, index, corner_indices); 00442 } 00443 00445 00446 DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3]) 00447 { 00448 DerivedMesh *dm = CDDM_from_mesh(me, ob); 00449 00450 if(!dm) 00451 return NULL; 00452 00453 if (vertCos) 00454 CDDM_apply_vert_coords(dm, vertCos); 00455 00456 CDDM_calc_normals(dm); 00457 00458 return dm; 00459 } 00460 00461 DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, ModifierData *md) 00462 { 00463 Mesh *me = ob->data; 00464 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00465 DerivedMesh *dm; 00466 00467 md->scene= scene; 00468 00469 if (!(md->mode&eModifierMode_Realtime)) return NULL; 00470 if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL; 00471 00472 if (mti->type==eModifierTypeType_OnlyDeform) { 00473 int numVerts; 00474 float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts); 00475 00476 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, 0, 0); 00477 dm = mesh_create_derived(me, ob, deformedVerts); 00478 00479 MEM_freeN(deformedVerts); 00480 } else { 00481 DerivedMesh *tdm = mesh_create_derived(me, ob, NULL); 00482 dm = mti->applyModifier(md, ob, tdm, 0, 0); 00483 00484 if(tdm != dm) tdm->release(tdm); 00485 } 00486 00487 return dm; 00488 } 00489 00490 static float *get_editmesh_orco_verts(EditMesh *em) 00491 { 00492 EditVert *eve; 00493 float *orco; 00494 int a, totvert; 00495 00496 /* these may not really be the orco's, but it's only for preview. 00497 * could be solver better once, but isn't simple */ 00498 00499 totvert= 0; 00500 for(eve=em->verts.first; eve; eve=eve->next) 00501 totvert++; 00502 00503 orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco"); 00504 00505 for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3) { 00506 copy_v3_v3(orco+a, eve->co); 00507 } 00508 00509 return orco; 00510 } 00511 00512 /* orco custom data layer */ 00513 00514 static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free) 00515 { 00516 *free= 0; 00517 00518 if(layer == CD_ORCO) { 00519 /* get original coordinates */ 00520 *free= 1; 00521 00522 if(em) 00523 return (float(*)[3])get_editmesh_orco_verts(em); 00524 else 00525 return (float(*)[3])get_mesh_orco_verts(ob); 00526 } 00527 else if(layer == CD_CLOTH_ORCO) { 00528 /* apply shape key for cloth, this should really be solved 00529 by a more flexible customdata system, but not simple */ 00530 if(!em) { 00531 ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); 00532 KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest); 00533 00534 if(kb->data) 00535 return kb->data; 00536 } 00537 00538 return NULL; 00539 } 00540 00541 return NULL; 00542 } 00543 00544 static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer) 00545 { 00546 DerivedMesh *dm; 00547 float (*orco)[3]; 00548 int free; 00549 00550 if(em) dm= CDDM_from_editmesh(em, me); 00551 else dm= CDDM_from_mesh(me, ob); 00552 00553 orco= get_orco_coords_dm(ob, em, layer, &free); 00554 00555 if(orco) { 00556 CDDM_apply_vert_coords(dm, orco); 00557 if(free) MEM_freeN(orco); 00558 } 00559 00560 CDDM_calc_normals(dm); 00561 00562 return dm; 00563 } 00564 00565 static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm, int layer) 00566 { 00567 float (*orco)[3], (*layerorco)[3]; 00568 int totvert, free; 00569 00570 totvert= dm->getNumVerts(dm); 00571 00572 if(orcodm) { 00573 orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco"); 00574 free= 1; 00575 00576 if(orcodm->getNumVerts(orcodm) == totvert) 00577 orcodm->getVertCos(orcodm, orco); 00578 else 00579 dm->getVertCos(dm, orco); 00580 } 00581 else 00582 orco= get_orco_coords_dm(ob, em, layer, &free); 00583 00584 if(orco) { 00585 if(layer == CD_ORCO) 00586 transform_mesh_orco_verts(ob->data, orco, totvert, 0); 00587 00588 if(!(layerorco = DM_get_vert_data_layer(dm, layer))) { 00589 DM_add_vert_layer(dm, layer, CD_CALLOC, NULL); 00590 layerorco = DM_get_vert_data_layer(dm, layer); 00591 } 00592 00593 memcpy(layerorco, orco, sizeof(float)*3*totvert); 00594 if(free) MEM_freeN(orco); 00595 } 00596 } 00597 00598 /* weight paint colors */ 00599 00600 /* Something of a hack, at the moment deal with weightpaint 00601 * by tucking into colors during modifier eval, only in 00602 * wpaint mode. Works ok but need to make sure recalc 00603 * happens on enter/exit wpaint. 00604 */ 00605 00606 void weight_to_rgb(float r_rgb[3], const float weight) 00607 { 00608 const float blend= ((weight/2.0f)+0.5f); 00609 00610 if (weight<=0.25f){ // blue->cyan 00611 r_rgb[0]= 0.0f; 00612 r_rgb[1]= blend*weight*4.0f; 00613 r_rgb[2]= blend; 00614 } 00615 else if (weight<=0.50f){ // cyan->green 00616 r_rgb[0]= 0.0f; 00617 r_rgb[1]= blend; 00618 r_rgb[2]= blend*(1.0f-((weight-0.25f)*4.0f)); 00619 } 00620 else if (weight <= 0.75f){ // green->yellow 00621 r_rgb[0]= blend * ((weight-0.50f)*4.0f); 00622 r_rgb[1]= blend; 00623 r_rgb[2]= 0.0f; 00624 } 00625 else if (weight <= 1.0f){ // yellow->red 00626 r_rgb[0]= blend; 00627 r_rgb[1]= blend * (1.0f-((weight-0.75f)*4.0f)); 00628 r_rgb[2]= 0.0f; 00629 } 00630 else { 00631 /* exceptional value, unclamped or nan, 00632 * avoid uninitialized memory use */ 00633 r_rgb[0]= 1.0f; 00634 r_rgb[1]= 0.0f; 00635 r_rgb[2]= 1.0f; 00636 } 00637 } 00638 00639 /* draw_flag's for calc_weightpaint_vert_color */ 00640 enum { 00641 CALC_WP_MULTIPAINT= (1<<0), 00642 CALC_WP_AUTO_NORMALIZE= (1<<1) 00643 }; 00644 00645 static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input) 00646 { 00647 float colf[4]; 00648 00649 if(coba) do_colorband(coba, input, colf); 00650 else weight_to_rgb(colf, input); 00651 00652 r_col[3] = (unsigned char)(colf[0] * 255.0f); 00653 r_col[2] = (unsigned char)(colf[1] * 255.0f); 00654 r_col[1] = (unsigned char)(colf[2] * 255.0f); 00655 r_col[0] = 255; 00656 } 00657 00658 00659 static void calc_weightpaint_vert_color( 00660 unsigned char r_col[4], 00661 MDeformVert *dv, ColorBand *coba, 00662 const int defbase_tot, const int defbase_act, 00663 const char *dg_flags, 00664 const int selected, const int draw_flag) 00665 { 00666 float input = 0.0f; 00667 00668 int make_black= FALSE; 00669 00670 if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) { 00671 int was_a_nonzero= FALSE; 00672 unsigned int i; 00673 00674 MDeformWeight *dw= dv->dw; 00675 for (i = dv->totweight; i != 0; i--, dw++) { 00676 /* in multipaint, get the average if auto normalize is inactive 00677 * get the sum if it is active */ 00678 if (dw->def_nr < defbase_tot) { 00679 if (dg_flags[dw->def_nr]) { 00680 if (dw->weight) { 00681 input += dw->weight; 00682 was_a_nonzero= TRUE; 00683 } 00684 } 00685 } 00686 } 00687 00688 /* make it black if the selected groups have no weight on a vertex */ 00689 if (was_a_nonzero == FALSE) { 00690 make_black = TRUE; 00691 } 00692 else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) { 00693 input /= selected; /* get the average */ 00694 } 00695 } 00696 else { 00697 /* default, non tricky behavior */ 00698 input= defvert_find_weight(dv, defbase_act); 00699 } 00700 00701 if (make_black) { /* TODO, theme color */ 00702 r_col[3] = 0; 00703 r_col[2] = 0; 00704 r_col[1] = 0; 00705 r_col[0] = 255; 00706 } 00707 else { 00708 CLAMP(input, 0.0f, 1.0f); 00709 weightpaint_color(r_col, coba, input); 00710 } 00711 } 00712 00713 static ColorBand *stored_cb= NULL; 00714 00715 void vDM_ColorBand_store(ColorBand *coba) 00716 { 00717 stored_cb= coba; 00718 } 00719 00720 /* return an array of vertex weight colors, caller must free. 00721 * 00722 * note that we could save some memory and allocate RGB only but then we'd need to 00723 * re-arrange the colors when copying to the face since MCol has odd ordering, 00724 * so leave this as is - campbell */ 00725 static unsigned char *calc_weightpaint_vert_array(Object *ob, int const draw_flag, ColorBand *coba) 00726 { 00727 Mesh *me = ob->data; 00728 unsigned char *wtcol_v = MEM_mallocN (sizeof(unsigned char) * me->totvert * 4, "weightmap_v"); 00729 00730 if (me->dvert) { 00731 unsigned char *wc = wtcol_v; 00732 MDeformVert *dv= me->dvert; 00733 unsigned int i; 00734 00735 /* varisbles for multipaint */ 00736 const int defbase_tot = BLI_countlist(&ob->defbase); 00737 const int defbase_act = ob->actdef-1; 00738 char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__); 00739 const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot); 00740 /* const int unselected = defbase_tot - selected; */ /* UNUSED */ 00741 00742 for (i = me->totvert; i != 0; i--, wc += 4, dv++) { 00743 calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, dg_flags, selected, draw_flag); 00744 } 00745 00746 MEM_freeN(dg_flags); 00747 } 00748 else { 00749 int col_i; 00750 weightpaint_color((unsigned char *)&col_i, coba, 0.0f); 00751 fill_vn_i((int *)wtcol_v, me->totvert, col_i); 00752 } 00753 00754 return wtcol_v; 00755 } 00756 00757 static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) 00758 { 00759 ColorBand *coba= stored_cb; /* warning, not a local var */ 00760 00761 Mesh *me = ob->data; 00762 unsigned char *wtcol_v = calc_weightpaint_vert_array(ob, draw_flag, coba); 00763 unsigned char *wtcol_f = MEM_mallocN (sizeof(unsigned char) * me->totface*4*4, "weightmap_f"); 00764 unsigned char *wtcol_f_step = wtcol_f; 00765 00766 MFace *mf = me->mface; 00767 int i; 00768 00769 for (i=0; i<me->totface; i++, mf++, wtcol_f_step += (4 * 4)) { 00770 #if 0 00771 unsigned int fidx= mf->v4 ? 3:2; 00772 00773 #else /* better zero out triangles 4th component. else valgrind complains when the buffer's copied */ 00774 unsigned int fidx; 00775 if (mf->v4) { 00776 fidx = 3; 00777 } 00778 else { 00779 fidx = 2; 00780 *(int *)(&wtcol_f_step[3 * 4]) = 0; 00781 } 00782 #endif 00783 00784 do { 00785 copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4], 00786 (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]); 00787 } while (fidx--); 00788 } 00789 00790 MEM_freeN(wtcol_v); 00791 00792 CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol_f, dm->numFaceData); 00793 } 00794 00795 /* new value for useDeform -1 (hack for the gameengine): 00796 * - apply only the modifier stack of the object, skipping the virtual modifiers, 00797 * - don't apply the key 00798 * - apply deform modifiers and input vertexco 00799 */ 00800 static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3], 00801 DerivedMesh **deform_r, DerivedMesh **final_r, 00802 int useRenderParams, int useDeform, 00803 int needMapping, CustomDataMask dataMask, int index, int useCache) 00804 { 00805 Mesh *me = ob->data; 00806 ModifierData *firstmd, *md; 00807 LinkNode *datamasks, *curr; 00808 CustomDataMask mask, nextmask, append_mask = 0; 00809 float (*deformedVerts)[3] = NULL; 00810 DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm; 00811 int numVerts = me->totvert; 00812 int required_mode; 00813 int isPrevDeform= FALSE; 00814 int skipVirtualArmature = (useDeform < 0); 00815 MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0); 00816 int has_multires = mmd != NULL, multires_applied = 0; 00817 int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt; 00818 00819 int draw_flag= ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) | 00820 (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0)); 00821 00822 if(mmd && !mmd->sculptlvl) 00823 has_multires = 0; 00824 00825 if(!skipVirtualArmature) { 00826 firstmd = modifiers_getVirtualModifierList(ob); 00827 } 00828 else { 00829 /* game engine exception */ 00830 firstmd = ob->modifiers.first; 00831 if(firstmd && firstmd->type == eModifierType_Armature) 00832 firstmd = firstmd->next; 00833 } 00834 00835 md = firstmd; 00836 00837 modifiers_clearErrors(ob); 00838 00839 if(useRenderParams) required_mode = eModifierMode_Render; 00840 else required_mode = eModifierMode_Realtime; 00841 00842 datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); 00843 curr = datamasks; 00844 00845 if(deform_r) *deform_r = NULL; 00846 *final_r = NULL; 00847 00848 if(useDeform) { 00849 if(inputVertexCos) 00850 deformedVerts = inputVertexCos; 00851 00852 /* Apply all leading deforming modifiers */ 00853 for(;md; md = md->next, curr = curr->next) { 00854 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00855 00856 md->scene= scene; 00857 00858 if(!modifier_isEnabled(scene, md, required_mode)) continue; 00859 if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; 00860 00861 if(mti->type == eModifierTypeType_OnlyDeform) { 00862 if(!deformedVerts) 00863 deformedVerts = mesh_getVertexCos(me, &numVerts); 00864 00865 mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, useRenderParams, useDeform); 00866 } else { 00867 break; 00868 } 00869 00870 /* grab modifiers until index i */ 00871 if((index >= 0) && (modifiers_indexInObject(ob, md) >= index)) 00872 break; 00873 } 00874 00875 /* Result of all leading deforming modifiers is cached for 00876 * places that wish to use the original mesh but with deformed 00877 * coordinates (vpaint, etc.) 00878 */ 00879 if (deform_r) { 00880 *deform_r = CDDM_from_mesh(me, ob); 00881 00882 if(deformedVerts) { 00883 CDDM_apply_vert_coords(*deform_r, deformedVerts); 00884 CDDM_calc_normals(*deform_r); 00885 } 00886 } 00887 } else { 00888 /* default behaviour for meshes */ 00889 if(inputVertexCos) 00890 deformedVerts = inputVertexCos; 00891 else 00892 deformedVerts = mesh_getVertexCos(me, &numVerts); 00893 } 00894 00895 00896 /* Now apply all remaining modifiers. If useDeform is off then skip 00897 * OnlyDeform ones. 00898 */ 00899 dm = NULL; 00900 orcodm = NULL; 00901 clothorcodm = NULL; 00902 00903 for(;md; md = md->next, curr = curr->next) { 00904 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00905 00906 md->scene= scene; 00907 00908 if(!modifier_isEnabled(scene, md, required_mode)) continue; 00909 if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue; 00910 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { 00911 modifier_setError(md, "Modifier requires original data, bad stack position."); 00912 continue; 00913 } 00914 if(sculpt_mode && (!has_multires || multires_applied)) { 00915 int unsupported= 0; 00916 00917 if(scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM) 00918 unsupported|= mti->type != eModifierTypeType_OnlyDeform; 00919 00920 unsupported|= md->type == eModifierType_Multires && ((MultiresModifierData*)md)->sculptlvl==0; 00921 unsupported|= multires_applied; 00922 00923 if(unsupported) { 00924 modifier_setError(md, "Not supported in sculpt mode."); 00925 continue; 00926 } 00927 } 00928 if(needMapping && !modifier_supportsMapping(md)) continue; 00929 if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; 00930 00931 /* add an orco layer if needed by this modifier */ 00932 if(mti->requiredDataMask) 00933 mask = mti->requiredDataMask(ob, md); 00934 else 00935 mask = 0; 00936 00937 if(dm && (mask & CD_MASK_ORCO)) 00938 add_orco_dm(ob, NULL, dm, orcodm, CD_ORCO); 00939 00940 /* How to apply modifier depends on (a) what we already have as 00941 * a result of previous modifiers (could be a DerivedMesh or just 00942 * deformed vertices) and (b) what type the modifier is. 00943 */ 00944 00945 if(mti->type == eModifierTypeType_OnlyDeform) { 00946 /* No existing verts to deform, need to build them. */ 00947 if(!deformedVerts) { 00948 if(dm) { 00949 /* Deforming a derived mesh, read the vertex locations 00950 * out of the mesh and deform them. Once done with this 00951 * run of deformers verts will be written back. 00952 */ 00953 numVerts = dm->getNumVerts(dm); 00954 deformedVerts = 00955 MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv"); 00956 dm->getVertCos(dm, deformedVerts); 00957 } else { 00958 deformedVerts = mesh_getVertexCos(me, &numVerts); 00959 } 00960 } 00961 00962 /* if this is not the last modifier in the stack then recalculate the normals 00963 * to avoid giving bogus normals to the next modifier see: [#23673] */ 00964 if(isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { 00965 /* XXX, this covers bug #23673, but we may need normal calc for other types */ 00966 if(dm && dm->type == DM_TYPE_CDDM) { 00967 CDDM_apply_vert_coords(dm, deformedVerts); 00968 CDDM_calc_normals(dm); 00969 } 00970 } 00971 00972 mti->deformVerts(md, ob, dm, deformedVerts, numVerts, useRenderParams, useDeform); 00973 } else { 00974 DerivedMesh *ndm; 00975 00976 /* determine which data layers are needed by following modifiers */ 00977 if(curr->next) 00978 nextmask= (CustomDataMask)GET_INT_FROM_POINTER(curr->next->link); 00979 else 00980 nextmask= dataMask; 00981 00982 /* apply vertex coordinates or build a DerivedMesh as necessary */ 00983 if(dm) { 00984 if(deformedVerts) { 00985 DerivedMesh *tdm = CDDM_copy(dm); 00986 dm->release(dm); 00987 dm = tdm; 00988 00989 CDDM_apply_vert_coords(dm, deformedVerts); 00990 CDDM_calc_normals(dm); 00991 } 00992 } else { 00993 dm = CDDM_from_mesh(me, ob); 00994 00995 if(deformedVerts) { 00996 CDDM_apply_vert_coords(dm, deformedVerts); 00997 CDDM_calc_normals(dm); 00998 } 00999 01000 if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) 01001 add_weight_mcol_dm(ob, dm, draw_flag); 01002 01003 /* Constructive modifiers need to have an origindex 01004 * otherwise they wont have anywhere to copy the data from. 01005 * 01006 * Also create ORIGINDEX data if any of the following modifiers 01007 * requests it, this way Mirror, Solidify etc will keep ORIGINDEX 01008 * data by using generic DM_copy_vert_data() functions. 01009 */ 01010 if(needMapping || (nextmask & CD_MASK_ORIGINDEX)) { 01011 /* calc */ 01012 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); 01013 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); 01014 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); 01015 01016 range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); 01017 range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); 01018 range_vn_i(DM_get_face_data_layer(dm, CD_ORIGINDEX), dm->numFaceData, 0); 01019 } 01020 } 01021 01022 01023 /* set the DerivedMesh to only copy needed data */ 01024 mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); 01025 /* needMapping check here fixes bug [#28112], otherwise its 01026 * possible that it wont be copied */ 01027 mask |= append_mask; 01028 DM_set_only_copy(dm, mask | (needMapping ? CD_MASK_ORIGINDEX : 0)); 01029 01030 /* add cloth rest shape key if need */ 01031 if(mask & CD_MASK_CLOTH_ORCO) 01032 add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO); 01033 01034 /* add an origspace layer if needed */ 01035 if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE) 01036 if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) 01037 DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); 01038 01039 ndm = mti->applyModifier(md, ob, dm, useRenderParams, useCache); 01040 01041 if(ndm) { 01042 /* if the modifier returned a new dm, release the old one */ 01043 if(dm && dm != ndm) dm->release(dm); 01044 01045 dm = ndm; 01046 01047 if(deformedVerts) { 01048 if(deformedVerts != inputVertexCos) 01049 MEM_freeN(deformedVerts); 01050 01051 deformedVerts = NULL; 01052 } 01053 } 01054 01055 /* create an orco derivedmesh in parallel */ 01056 if(nextmask & CD_MASK_ORCO) { 01057 if(!orcodm) 01058 orcodm= create_orco_dm(ob, me, NULL, CD_ORCO); 01059 01060 nextmask &= ~CD_MASK_ORCO; 01061 DM_set_only_copy(orcodm, nextmask | CD_MASK_ORIGINDEX); 01062 ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0); 01063 01064 if(ndm) { 01065 /* if the modifier returned a new dm, release the old one */ 01066 if(orcodm && orcodm != ndm) orcodm->release(orcodm); 01067 orcodm = ndm; 01068 } 01069 } 01070 01071 /* create cloth orco derivedmesh in parallel */ 01072 if(nextmask & CD_MASK_CLOTH_ORCO) { 01073 if(!clothorcodm) 01074 clothorcodm= create_orco_dm(ob, me, NULL, CD_CLOTH_ORCO); 01075 01076 nextmask &= ~CD_MASK_CLOTH_ORCO; 01077 DM_set_only_copy(clothorcodm, nextmask | CD_MASK_ORIGINDEX); 01078 ndm = mti->applyModifier(md, ob, clothorcodm, useRenderParams, 0); 01079 01080 if(ndm) { 01081 /* if the modifier returned a new dm, release the old one */ 01082 if(clothorcodm && clothorcodm != ndm) clothorcodm->release(clothorcodm); 01083 clothorcodm = ndm; 01084 } 01085 } 01086 01087 /* in case of dynamic paint, make sure preview mask remains for following modifiers */ 01088 if (md->type == eModifierType_DynamicPaint) 01089 append_mask |= CD_MASK_WEIGHT_MCOL; 01090 } 01091 01092 isPrevDeform= (mti->type == eModifierTypeType_OnlyDeform); 01093 01094 /* grab modifiers until index i */ 01095 if((index >= 0) && (modifiers_indexInObject(ob, md) >= index)) 01096 break; 01097 01098 if(sculpt_mode && md->type == eModifierType_Multires) 01099 multires_applied = 1; 01100 } 01101 01102 for(md=firstmd; md; md=md->next) 01103 modifier_freeTemporaryData(md); 01104 01105 /* Yay, we are done. If we have a DerivedMesh and deformed vertices 01106 * need to apply these back onto the DerivedMesh. If we have no 01107 * DerivedMesh then we need to build one. 01108 */ 01109 if(dm && deformedVerts) { 01110 finaldm = CDDM_copy(dm); 01111 01112 dm->release(dm); 01113 01114 CDDM_apply_vert_coords(finaldm, deformedVerts); 01115 CDDM_calc_normals(finaldm); 01116 01117 if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) 01118 add_weight_mcol_dm(ob, finaldm, draw_flag); 01119 } else if(dm) { 01120 finaldm = dm; 01121 } else { 01122 finaldm = CDDM_from_mesh(me, ob); 01123 01124 if(deformedVerts) { 01125 CDDM_apply_vert_coords(finaldm, deformedVerts); 01126 CDDM_calc_normals(finaldm); 01127 } 01128 01129 if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) 01130 add_weight_mcol_dm(ob, finaldm, draw_flag); 01131 } 01132 01133 /* add an orco layer if needed */ 01134 if(dataMask & CD_MASK_ORCO) { 01135 add_orco_dm(ob, NULL, finaldm, orcodm, CD_ORCO); 01136 01137 if(deform_r && *deform_r) 01138 add_orco_dm(ob, NULL, *deform_r, NULL, CD_ORCO); 01139 } 01140 01141 #ifdef WITH_GAMEENGINE 01142 /* NavMesh - this is a hack but saves having a NavMesh modifier */ 01143 if ((ob->gameflag & OB_NAVMESH) && (finaldm->type == DM_TYPE_CDDM)) { 01144 DerivedMesh *tdm; 01145 tdm= navmesh_dm_createNavMeshForVisualization(finaldm); 01146 if (finaldm != tdm) { 01147 finaldm->release(finaldm); 01148 finaldm= tdm; 01149 } 01150 } 01151 #endif /* WITH_GAMEENGINE */ 01152 01153 *final_r = finaldm; 01154 01155 if(orcodm) 01156 orcodm->release(orcodm); 01157 if(clothorcodm) 01158 clothorcodm->release(clothorcodm); 01159 01160 if(deformedVerts && deformedVerts != inputVertexCos) 01161 MEM_freeN(deformedVerts); 01162 01163 BLI_linklist_free(datamasks, NULL); 01164 } 01165 01166 float (*editmesh_get_vertex_cos(EditMesh *em, int *numVerts_r))[3] 01167 { 01168 int i, numVerts = *numVerts_r = BLI_countlist(&em->verts); 01169 float (*cos)[3]; 01170 EditVert *eve; 01171 01172 cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos"); 01173 for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) { 01174 copy_v3_v3(cos[i], eve->co); 01175 } 01176 01177 return cos; 01178 } 01179 01180 int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm) 01181 { 01182 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 01183 int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; 01184 01185 if(!modifier_isEnabled(scene, md, required_mode)) return 0; 01186 if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { 01187 modifier_setError(md, "Modifier requires original data, bad stack position."); 01188 return 0; 01189 } 01190 01191 return 1; 01192 } 01193 01194 static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, DerivedMesh **cage_r, 01195 DerivedMesh **final_r, 01196 CustomDataMask dataMask) 01197 { 01198 ModifierData *md; 01199 float (*deformedVerts)[3] = NULL; 01200 CustomDataMask mask; 01201 DerivedMesh *dm, *orcodm = NULL; 01202 int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1); 01203 LinkNode *datamasks, *curr; 01204 int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; 01205 01206 modifiers_clearErrors(ob); 01207 01208 if(cage_r && cageIndex == -1) { 01209 *cage_r = editmesh_get_derived(em, NULL); 01210 } 01211 01212 dm = NULL; 01213 md = modifiers_getVirtualModifierList(ob); 01214 01215 datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); 01216 01217 curr = datamasks; 01218 for(i = 0; md; i++, md = md->next, curr = curr->next) { 01219 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 01220 01221 md->scene= scene; 01222 01223 if(!editmesh_modifier_is_enabled(scene, md, dm)) 01224 continue; 01225 01226 /* add an orco layer if needed by this modifier */ 01227 if(dm && mti->requiredDataMask) { 01228 mask = mti->requiredDataMask(ob, md); 01229 if(mask & CD_MASK_ORCO) 01230 add_orco_dm(ob, em, dm, orcodm, CD_ORCO); 01231 } 01232 01233 /* How to apply modifier depends on (a) what we already have as 01234 * a result of previous modifiers (could be a DerivedMesh or just 01235 * deformed vertices) and (b) what type the modifier is. 01236 */ 01237 01238 if(mti->type == eModifierTypeType_OnlyDeform) { 01239 /* No existing verts to deform, need to build them. */ 01240 if(!deformedVerts) { 01241 if(dm) { 01242 /* Deforming a derived mesh, read the vertex locations 01243 * out of the mesh and deform them. Once done with this 01244 * run of deformers verts will be written back. 01245 */ 01246 numVerts = dm->getNumVerts(dm); 01247 deformedVerts = 01248 MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv"); 01249 dm->getVertCos(dm, deformedVerts); 01250 } else { 01251 deformedVerts = editmesh_get_vertex_cos(em, &numVerts); 01252 } 01253 } 01254 01255 if (mti->deformVertsEM) 01256 mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts); 01257 else mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0, 0); 01258 } else { 01259 DerivedMesh *ndm; 01260 01261 /* apply vertex coordinates or build a DerivedMesh as necessary */ 01262 if(dm) { 01263 if(deformedVerts) { 01264 DerivedMesh *tdm = CDDM_copy(dm); 01265 if(!(cage_r && dm == *cage_r)) dm->release(dm); 01266 dm = tdm; 01267 01268 CDDM_apply_vert_coords(dm, deformedVerts); 01269 CDDM_calc_normals(dm); 01270 } else if(cage_r && dm == *cage_r) { 01271 /* dm may be changed by this modifier, so we need to copy it 01272 */ 01273 dm = CDDM_copy(dm); 01274 } 01275 01276 } else { 01277 dm = CDDM_from_editmesh(em, ob->data); 01278 01279 if(deformedVerts) { 01280 CDDM_apply_vert_coords(dm, deformedVerts); 01281 CDDM_calc_normals(dm); 01282 } 01283 } 01284 01285 /* create an orco derivedmesh in parallel */ 01286 mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); 01287 if(mask & CD_MASK_ORCO) { 01288 if(!orcodm) 01289 orcodm= create_orco_dm(ob, ob->data, em, CD_ORCO); 01290 01291 mask &= ~CD_MASK_ORCO; 01292 DM_set_only_copy(orcodm, mask | CD_MASK_ORIGINDEX); 01293 01294 if (mti->applyModifierEM) 01295 ndm = mti->applyModifierEM(md, ob, em, orcodm); 01296 else 01297 ndm = mti->applyModifier(md, ob, orcodm, 0, 0); 01298 01299 if(ndm) { 01300 /* if the modifier returned a new dm, release the old one */ 01301 if(orcodm && orcodm != ndm) orcodm->release(orcodm); 01302 orcodm = ndm; 01303 } 01304 } 01305 01306 /* set the DerivedMesh to only copy needed data */ 01307 mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link); /* CD_MASK_ORCO may have been cleared above */ 01308 01309 DM_set_only_copy(dm, mask | CD_MASK_ORIGINDEX); 01310 01311 if(mask & CD_MASK_ORIGSPACE) 01312 if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE)) 01313 DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL); 01314 01315 if (mti->applyModifierEM) 01316 ndm = mti->applyModifierEM(md, ob, em, dm); 01317 else 01318 ndm = mti->applyModifier(md, ob, dm, 0, 0); 01319 01320 if (ndm) { 01321 if(dm && dm != ndm) 01322 dm->release(dm); 01323 01324 dm = ndm; 01325 01326 if (deformedVerts) { 01327 MEM_freeN(deformedVerts); 01328 deformedVerts = NULL; 01329 } 01330 } 01331 } 01332 01333 if(cage_r && i == cageIndex) { 01334 if(dm && deformedVerts) { 01335 *cage_r = CDDM_copy(dm); 01336 CDDM_apply_vert_coords(*cage_r, deformedVerts); 01337 } else if(dm) { 01338 *cage_r = dm; 01339 } else { 01340 *cage_r = 01341 editmesh_get_derived(em, 01342 deformedVerts ? MEM_dupallocN(deformedVerts) : NULL); 01343 } 01344 } 01345 } 01346 01347 BLI_linklist_free(datamasks, NULL); 01348 01349 /* Yay, we are done. If we have a DerivedMesh and deformed vertices need 01350 * to apply these back onto the DerivedMesh. If we have no DerivedMesh 01351 * then we need to build one. 01352 */ 01353 if(dm && deformedVerts) { 01354 *final_r = CDDM_copy(dm); 01355 01356 if(!(cage_r && dm == *cage_r)) dm->release(dm); 01357 01358 CDDM_apply_vert_coords(*final_r, deformedVerts); 01359 CDDM_calc_normals(*final_r); 01360 } else if (dm) { 01361 *final_r = dm; 01362 } else if (!deformedVerts && cage_r && *cage_r) { 01363 *final_r = *cage_r; 01364 } else { 01365 *final_r = editmesh_get_derived(em, deformedVerts); 01366 deformedVerts = NULL; 01367 } 01368 01369 /* add an orco layer if needed */ 01370 if(dataMask & CD_MASK_ORCO) 01371 add_orco_dm(ob, em, *final_r, orcodm, CD_ORCO); 01372 01373 if(orcodm) 01374 orcodm->release(orcodm); 01375 01376 if(deformedVerts) 01377 MEM_freeN(deformedVerts); 01378 } 01379 01380 static void clear_mesh_caches(Object *ob) 01381 { 01382 Mesh *me= ob->data; 01383 01384 /* also serves as signal to remake texspace */ 01385 if (ob->bb) { 01386 MEM_freeN(ob->bb); 01387 ob->bb = NULL; 01388 } 01389 if (me->bb) { 01390 MEM_freeN(me->bb); 01391 me->bb = NULL; 01392 } 01393 01394 freedisplist(&ob->disp); 01395 01396 if (ob->derivedFinal) { 01397 ob->derivedFinal->needsFree = 1; 01398 ob->derivedFinal->release(ob->derivedFinal); 01399 ob->derivedFinal= NULL; 01400 } 01401 if (ob->derivedDeform) { 01402 ob->derivedDeform->needsFree = 1; 01403 ob->derivedDeform->release(ob->derivedDeform); 01404 ob->derivedDeform= NULL; 01405 } 01406 01407 if(ob->sculpt) { 01408 object_sculpt_modifiers_changed(ob); 01409 } 01410 } 01411 01412 static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask) 01413 { 01414 Object *obact = scene->basact?scene->basact->object:NULL; 01415 int editing = paint_facesel_test(ob) || paint_vertsel_test(ob);/* paint_vertsel_test */ 01416 /* weight paint and face select need original indices because of selection buffer drawing */ 01417 int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT))); 01418 01419 clear_mesh_caches(ob); 01420 01421 mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform, 01422 &ob->derivedFinal, 0, 1, 01423 needMapping, dataMask, -1, 1); 01424 01425 DM_set_object_boundbox (ob, ob->derivedFinal); 01426 01427 ob->derivedFinal->needsFree = 0; 01428 ob->derivedDeform->needsFree = 0; 01429 ob->lastDataMask = dataMask; 01430 } 01431 01432 static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask) 01433 { 01434 clear_mesh_caches(obedit); 01435 01436 if (em->derivedFinal) { 01437 if (em->derivedFinal!=em->derivedCage) { 01438 em->derivedFinal->needsFree = 1; 01439 em->derivedFinal->release(em->derivedFinal); 01440 } 01441 em->derivedFinal = NULL; 01442 } 01443 if (em->derivedCage) { 01444 em->derivedCage->needsFree = 1; 01445 em->derivedCage->release(em->derivedCage); 01446 em->derivedCage = NULL; 01447 } 01448 01449 editmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask); 01450 DM_set_object_boundbox (obedit, em->derivedFinal); 01451 01452 em->lastDataMask = dataMask; 01453 em->derivedFinal->needsFree = 0; 01454 em->derivedCage->needsFree = 0; 01455 } 01456 01457 void makeDerivedMesh(Scene *scene, Object *ob, EditMesh *em, CustomDataMask dataMask) 01458 { 01459 if (em) { 01460 editmesh_build_data(scene, ob, em, dataMask); 01461 } else { 01462 mesh_build_data(scene, ob, dataMask); 01463 } 01464 } 01465 01466 /***/ 01467 01468 DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dataMask) 01469 { 01470 /* if there's no derived mesh or the last data mask used doesn't include 01471 * the data we need, rebuild the derived mesh 01472 */ 01473 if(!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask) 01474 mesh_build_data(scene, ob, dataMask); 01475 01476 return ob->derivedFinal; 01477 } 01478 01479 DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask dataMask) 01480 { 01481 /* if there's no derived mesh or the last data mask used doesn't include 01482 * the data we need, rebuild the derived mesh 01483 */ 01484 if(!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask) 01485 mesh_build_data(scene, ob, dataMask); 01486 01487 return ob->derivedDeform; 01488 } 01489 01490 DerivedMesh *mesh_create_derived_render(Scene *scene, Object *ob, CustomDataMask dataMask) 01491 { 01492 DerivedMesh *final; 01493 01494 mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1, 0); 01495 01496 return final; 01497 } 01498 01499 DerivedMesh *mesh_create_derived_index_render(Scene *scene, Object *ob, CustomDataMask dataMask, int index) 01500 { 01501 DerivedMesh *final; 01502 01503 mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, index, 0); 01504 01505 return final; 01506 } 01507 01508 DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask dataMask) 01509 { 01510 DerivedMesh *final; 01511 01512 mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0); 01513 01514 return final; 01515 } 01516 01517 DerivedMesh *mesh_create_derived_no_deform(Scene *scene, Object *ob, float (*vertCos)[3], 01518 CustomDataMask dataMask) 01519 { 01520 DerivedMesh *final; 01521 01522 mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, 0, 0, dataMask, -1, 0); 01523 01524 return final; 01525 } 01526 01527 DerivedMesh *mesh_create_derived_no_virtual(Scene *scene, Object *ob, float (*vertCos)[3], 01528 CustomDataMask dataMask) 01529 { 01530 DerivedMesh *final; 01531 01532 mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1, 0); 01533 01534 return final; 01535 } 01536 01537 DerivedMesh *mesh_create_derived_physics(Scene *scene, Object *ob, float (*vertCos)[3], 01538 CustomDataMask dataMask) 01539 { 01540 DerivedMesh *final; 01541 01542 mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 0, -1, 1, dataMask, -1, 0); 01543 01544 return final; 01545 } 01546 01547 DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob, 01548 float (*vertCos)[3], 01549 CustomDataMask dataMask) 01550 { 01551 DerivedMesh *final; 01552 01553 mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 1, 0, 0, dataMask, -1, 0); 01554 01555 return final; 01556 } 01557 01558 /***/ 01559 01560 DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, EditMesh *em, DerivedMesh **final_r, 01561 CustomDataMask dataMask) 01562 { 01563 /* if there's no derived mesh or the last data mask used doesn't include 01564 * the data we need, rebuild the derived mesh 01565 */ 01566 if(!em->derivedCage || 01567 (em->lastDataMask & dataMask) != dataMask) 01568 editmesh_build_data(scene, obedit, em, dataMask); 01569 01570 *final_r = em->derivedFinal; 01571 return em->derivedCage; 01572 } 01573 01574 DerivedMesh *editmesh_get_derived_cage(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask) 01575 { 01576 /* if there's no derived mesh or the last data mask used doesn't include 01577 * the data we need, rebuild the derived mesh 01578 */ 01579 if(!em->derivedCage || 01580 (em->lastDataMask & dataMask) != dataMask) 01581 editmesh_build_data(scene, obedit, em, dataMask); 01582 01583 return em->derivedCage; 01584 } 01585 01586 DerivedMesh *editmesh_get_derived_base(Object *UNUSED(obedit), EditMesh *em) 01587 { 01588 return editmesh_get_derived(em, NULL); 01589 } 01590 01591 01592 /* ********* For those who don't grasp derived stuff! (ton) :) *************** */ 01593 01594 static void make_vertexcosnos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) 01595 { 01596 float *vec = userData; 01597 01598 vec+= 6*index; 01599 01600 /* check if we've been here before (normal should not be 0) */ 01601 if(vec[3] || vec[4] || vec[5]) return; 01602 01603 copy_v3_v3(vec, co); 01604 vec+= 3; 01605 if(no_f) { 01606 copy_v3_v3(vec, no_f); 01607 } 01608 else { 01609 normal_short_to_float_v3(vec, no_s); 01610 } 01611 } 01612 01613 /* always returns original amount me->totvert of vertices and normals, but fully deformed and subsurfered */ 01614 /* this is needed for all code using vertexgroups (no subsurf support) */ 01615 /* it stores the normals as floats, but they can still be scaled as shorts (32767 = unit) */ 01616 /* in use now by vertex/weight paint and particle generating */ 01617 01618 float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob) 01619 { 01620 Mesh *me= ob->data; 01621 DerivedMesh *dm; 01622 float *vertexcosnos; 01623 01624 /* lets prevent crashing... */ 01625 if(ob->type!=OB_MESH || me->totvert==0) 01626 return NULL; 01627 01628 dm= mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); 01629 vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map"); 01630 01631 if(dm->foreachMappedVert) { 01632 dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos); 01633 } 01634 else { 01635 float *fp= vertexcosnos; 01636 int a; 01637 01638 for(a=0; a< me->totvert; a++, fp+=6) { 01639 dm->getVertCo(dm, a, fp); 01640 dm->getVertNo(dm, a, fp+3); 01641 } 01642 } 01643 01644 dm->release(dm); 01645 return vertexcosnos; 01646 } 01647 01648 /* ******************* GLSL ******************** */ 01649 01650 typedef struct 01651 { 01652 float * precomputedFaceNormals; 01653 MTFace * mtface; // texture coordinates 01654 MFace * mface; // indices 01655 MVert * mvert; // vertices & normals 01656 float (*orco)[3]; 01657 float (*tangent)[4]; // destination 01658 int numFaces; 01659 01660 } SGLSLMeshToTangent; 01661 01662 // interface 01663 #include "mikktspace.h" 01664 01665 static int GetNumFaces(const SMikkTSpaceContext * pContext) 01666 { 01667 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 01668 return pMesh->numFaces; 01669 } 01670 01671 static int GetNumVertsOfFace(const SMikkTSpaceContext * pContext, const int face_num) 01672 { 01673 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 01674 return pMesh->mface[face_num].v4!=0 ? 4 : 3; 01675 } 01676 01677 static void GetPosition(const SMikkTSpaceContext * pContext, float fPos[], const int face_num, const int vert_index) 01678 { 01679 //assert(vert_index>=0 && vert_index<4); 01680 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 01681 const float *co= pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].co; 01682 copy_v3_v3(fPos, co); 01683 } 01684 01685 static void GetTextureCoordinate(const SMikkTSpaceContext * pContext, float fUV[], const int face_num, const int vert_index) 01686 { 01687 //assert(vert_index>=0 && vert_index<4); 01688 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 01689 01690 if(pMesh->mtface!=NULL) { 01691 float * uv = pMesh->mtface[face_num].uv[vert_index]; 01692 fUV[0]=uv[0]; fUV[1]=uv[1]; 01693 } 01694 else { 01695 const float *orco= pMesh->orco[(&pMesh->mface[face_num].v1)[vert_index]]; 01696 map_to_sphere( &fUV[0], &fUV[1], orco[0], orco[1], orco[2]); 01697 } 01698 } 01699 01700 static void GetNormal(const SMikkTSpaceContext * pContext, float fNorm[], const int face_num, const int vert_index) 01701 { 01702 //assert(vert_index>=0 && vert_index<4); 01703 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 01704 01705 const int smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH); 01706 if(!smoothnormal) { // flat 01707 if(pMesh->precomputedFaceNormals) { 01708 copy_v3_v3(fNorm, &pMesh->precomputedFaceNormals[3*face_num]); 01709 } 01710 else { 01711 MFace *mf= &pMesh->mface[face_num]; 01712 float *p0= pMesh->mvert[mf->v1].co; 01713 float *p1= pMesh->mvert[mf->v2].co; 01714 float *p2= pMesh->mvert[mf->v3].co; 01715 01716 if(mf->v4) { 01717 float *p3 = pMesh->mvert[mf->v4].co; 01718 normal_quad_v3(fNorm, p0, p1, p2, p3); 01719 } 01720 else { 01721 normal_tri_v3(fNorm, p0, p1, p2); 01722 } 01723 } 01724 } 01725 else { 01726 const short *no= pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].no; 01727 normal_short_to_float_v3(fNorm, no); 01728 } 01729 } 01730 static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int face_num, const int iVert) 01731 { 01732 //assert(vert_index>=0 && vert_index<4); 01733 SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; 01734 float * pRes = pMesh->tangent[4*face_num+iVert]; 01735 copy_v3_v3(pRes, fvTangent); 01736 pRes[3]=fSign; 01737 } 01738 01739 01740 void DM_add_tangent_layer(DerivedMesh *dm) 01741 { 01742 /* mesh vars */ 01743 MTFace *mtface, *tf; 01744 MFace *mface, *mf; 01745 MVert *mvert, *v1, *v2, *v3, *v4; 01746 MemArena *arena= NULL; 01747 VertexTangent **vtangents= NULL; 01748 float (*orco)[3]= NULL, (*tangent)[4]; 01749 float *uv1, *uv2, *uv3, *uv4, *vtang; 01750 float fno[3], tang[3], uv[4][2]; 01751 int i, j, len, mf_vi[4], totvert, totface, iCalcNewMethod; 01752 float *nors; 01753 01754 if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1) 01755 return; 01756 01757 nors = dm->getFaceDataArray(dm, CD_NORMAL); 01758 01759 /* check we have all the needed layers */ 01760 totvert= dm->getNumVerts(dm); 01761 totface= dm->getNumFaces(dm); 01762 01763 mvert= dm->getVertArray(dm); 01764 mface= dm->getFaceArray(dm); 01765 mtface= dm->getFaceDataArray(dm, CD_MTFACE); 01766 01767 if(!mtface) { 01768 orco= dm->getVertDataArray(dm, CD_ORCO); 01769 if(!orco) 01770 return; 01771 } 01772 01773 /* create tangent layer */ 01774 DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL); 01775 tangent= DM_get_face_data_layer(dm, CD_TANGENT); 01776 01777 /* allocate some space */ 01778 arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "tangent layer arena"); 01779 BLI_memarena_use_calloc(arena); 01780 vtangents= MEM_callocN(sizeof(VertexTangent*)*totvert, "VertexTangent"); 01781 01782 // new computation method 01783 iCalcNewMethod = 1; 01784 if(iCalcNewMethod != 0) { 01785 SGLSLMeshToTangent mesh2tangent= {0}; 01786 SMikkTSpaceContext sContext= {0}; 01787 SMikkTSpaceInterface sInterface= {0}; 01788 01789 mesh2tangent.precomputedFaceNormals = nors; 01790 mesh2tangent.mtface = mtface; 01791 mesh2tangent.mface = mface; 01792 mesh2tangent.mvert = mvert; 01793 mesh2tangent.orco = orco; 01794 mesh2tangent.tangent = tangent; 01795 mesh2tangent.numFaces = totface; 01796 01797 sContext.m_pUserData = &mesh2tangent; 01798 sContext.m_pInterface = &sInterface; 01799 sInterface.m_getNumFaces = GetNumFaces; 01800 sInterface.m_getNumVerticesOfFace = GetNumVertsOfFace; 01801 sInterface.m_getPosition = GetPosition; 01802 sInterface.m_getTexCoord = GetTextureCoordinate; 01803 sInterface.m_getNormal = GetNormal; 01804 sInterface.m_setTSpaceBasic = SetTSpace; 01805 01806 // 0 if failed 01807 iCalcNewMethod = genTangSpaceDefault(&sContext); 01808 } 01809 01810 if(!iCalcNewMethod) { 01811 /* sum tangents at connected vertices */ 01812 for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) { 01813 v1= &mvert[mf->v1]; 01814 v2= &mvert[mf->v2]; 01815 v3= &mvert[mf->v3]; 01816 01817 if (mf->v4) { 01818 v4= &mvert[mf->v4]; 01819 normal_quad_v3( fno,v4->co, v3->co, v2->co, v1->co); 01820 } 01821 else { 01822 v4= NULL; 01823 normal_tri_v3( fno,v3->co, v2->co, v1->co); 01824 } 01825 01826 if(mtface) { 01827 uv1= tf->uv[0]; 01828 uv2= tf->uv[1]; 01829 uv3= tf->uv[2]; 01830 uv4= tf->uv[3]; 01831 } 01832 else { 01833 uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3]; 01834 map_to_sphere( &uv[0][0], &uv[0][1],orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2]); 01835 map_to_sphere( &uv[1][0], &uv[1][1],orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2]); 01836 map_to_sphere( &uv[2][0], &uv[2][1],orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2]); 01837 if(v4) 01838 map_to_sphere( &uv[3][0], &uv[3][1],orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2]); 01839 } 01840 01841 tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang); 01842 sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); 01843 sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2); 01844 sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); 01845 01846 if(mf->v4) { 01847 v4= &mvert[mf->v4]; 01848 01849 tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang); 01850 sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); 01851 sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); 01852 sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4); 01853 } 01854 } 01855 01856 /* write tangent to layer */ 01857 for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++, tangent+=4) { 01858 len= (mf->v4)? 4 : 3; 01859 01860 if(mtface == NULL) { 01861 map_to_sphere( &uv[0][0], &uv[0][1],orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2]); 01862 map_to_sphere( &uv[1][0], &uv[1][1],orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2]); 01863 map_to_sphere( &uv[2][0], &uv[2][1],orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2]); 01864 if(len==4) 01865 map_to_sphere( &uv[3][0], &uv[3][1],orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2]); 01866 } 01867 01868 mf_vi[0]= mf->v1; 01869 mf_vi[1]= mf->v2; 01870 mf_vi[2]= mf->v3; 01871 mf_vi[3]= mf->v4; 01872 01873 for(j=0; j<len; j++) { 01874 vtang= find_vertex_tangent(vtangents[mf_vi[j]], mtface ? tf->uv[j] : uv[j]); 01875 normalize_v3_v3(tangent[j], vtang); 01876 ((float *) tangent[j])[3]=1.0f; 01877 } 01878 } 01879 } 01880 01881 BLI_memarena_free(arena); 01882 MEM_freeN(vtangents); 01883 } 01884 01885 void DM_calc_auto_bump_scale(DerivedMesh *dm) 01886 { 01887 /* int totvert= dm->getNumVerts(dm); */ /* UNUSED */ 01888 int totface= dm->getNumFaces(dm); 01889 01890 MVert * mvert = dm->getVertArray(dm); 01891 MFace * mface = dm->getFaceArray(dm); 01892 MTFace * mtface = dm->getFaceDataArray(dm, CD_MTFACE); 01893 01894 if(mtface) 01895 { 01896 double dsum = 0.0; 01897 int nr_accumulated = 0; 01898 int f; 01899 01900 for ( f=0; f<totface; f++ ) 01901 { 01902 { 01903 float * verts[4], * tex_coords[4]; 01904 const int nr_verts = mface[f].v4!=0 ? 4 : 3; 01905 int i, is_degenerate; 01906 01907 verts[0]=mvert[mface[f].v1].co; verts[1]=mvert[mface[f].v2].co; verts[2]=mvert[mface[f].v3].co; 01908 tex_coords[0]=mtface[f].uv[0]; tex_coords[1]=mtface[f].uv[1]; tex_coords[2]=mtface[f].uv[2]; 01909 if(nr_verts==4) 01910 { 01911 verts[3]=mvert[mface[f].v4].co; 01912 tex_coords[3]=mtface[f].uv[3]; 01913 } 01914 01915 // discard degenerate faces 01916 is_degenerate = 0; 01917 if( equals_v3v3(verts[0], verts[1]) || equals_v3v3(verts[0], verts[2]) || equals_v3v3(verts[1], verts[2]) || 01918 equals_v2v2(tex_coords[0], tex_coords[1]) || equals_v2v2(tex_coords[0], tex_coords[2]) || equals_v2v2(tex_coords[1], tex_coords[2]) ) 01919 { 01920 is_degenerate = 1; 01921 } 01922 01923 // verify last vertex as well if this is a quad 01924 if ( is_degenerate==0 && nr_verts==4 ) 01925 { 01926 if( equals_v3v3(verts[3], verts[0]) || equals_v3v3(verts[3], verts[1]) || equals_v3v3(verts[3], verts[2]) || 01927 equals_v2v2(tex_coords[3], tex_coords[0]) || equals_v2v2(tex_coords[3], tex_coords[1]) || equals_v2v2(tex_coords[3], tex_coords[2]) ) 01928 { 01929 is_degenerate = 1; 01930 } 01931 01932 // verify the winding is consistent 01933 if ( is_degenerate==0 ) 01934 { 01935 float prev_edge[2]; 01936 int is_signed = 0; 01937 sub_v2_v2v2(prev_edge, tex_coords[0], tex_coords[3]); 01938 01939 i = 0; 01940 while ( is_degenerate==0 && i<4 ) 01941 { 01942 float cur_edge[2], signed_area; 01943 sub_v2_v2v2(cur_edge, tex_coords[(i+1)&0x3], tex_coords[i]); 01944 signed_area = prev_edge[0]*cur_edge[1] - prev_edge[1]*cur_edge[0]; 01945 if ( i==0 ) is_signed = signed_area<0.0f ? 1 : 0; 01946 else if((is_signed!=0)!=(signed_area<0.0f)) is_degenerate=1; 01947 01948 if ( is_degenerate==0 ) 01949 { 01950 copy_v2_v2(prev_edge, cur_edge); 01951 ++i; 01952 } 01953 } 01954 } 01955 } 01956 01957 // proceed if not a degenerate face 01958 if ( is_degenerate==0 ) 01959 { 01960 int nr_tris_to_pile=0; 01961 // quads split at shortest diagonal 01962 int offs = 0; // initial triangulation is 0,1,2 and 0, 2, 3 01963 if ( nr_verts==4 ) 01964 { 01965 float pos_len_diag0, pos_len_diag1; 01966 float vtmp[3]; 01967 sub_v3_v3v3(vtmp, verts[2], verts[0]); 01968 pos_len_diag0 = dot_v3v3(vtmp, vtmp); 01969 sub_v3_v3v3(vtmp, verts[3], verts[1]); 01970 pos_len_diag1 = dot_v3v3(vtmp, vtmp); 01971 01972 if(pos_len_diag1<pos_len_diag0) 01973 offs=1; // alter split 01974 else if(pos_len_diag0==pos_len_diag1) // do UV check instead 01975 { 01976 float tex_len_diag0, tex_len_diag1; 01977 01978 sub_v2_v2v2(vtmp, tex_coords[2], tex_coords[0]); 01979 tex_len_diag0 = dot_v2v2(vtmp, vtmp); 01980 sub_v2_v2v2(vtmp, tex_coords[3], tex_coords[1]); 01981 tex_len_diag1 = dot_v2v2(vtmp, vtmp); 01982 01983 if(tex_len_diag1<tex_len_diag0) 01984 { 01985 offs=1; // alter split 01986 } 01987 } 01988 } 01989 nr_tris_to_pile = nr_verts-2 ; 01990 if ( nr_tris_to_pile==1 || nr_tris_to_pile==2 ) 01991 { 01992 const int indices[] = {offs+0, offs+1, offs+2, offs+0, offs+2, (offs+3)&0x3 }; 01993 int t; 01994 for ( t=0; t<nr_tris_to_pile; t++ ) 01995 { 01996 float f2x_area_uv; 01997 float * p0 = verts[indices[t*3+0]]; 01998 float * p1 = verts[indices[t*3+1]]; 01999 float * p2 = verts[indices[t*3+2]]; 02000 02001 float edge_t0[2], edge_t1[2]; 02002 sub_v2_v2v2(edge_t0, tex_coords[indices[t*3+1]], tex_coords[indices[t*3+0]]); 02003 sub_v2_v2v2(edge_t1, tex_coords[indices[t*3+2]], tex_coords[indices[t*3+0]]); 02004 02005 f2x_area_uv = fabsf(edge_t0[0]*edge_t1[1] - edge_t0[1]*edge_t1[0]); 02006 if ( f2x_area_uv>FLT_EPSILON ) 02007 { 02008 float norm[3], v0[3], v1[3], f2x_surf_area, fsurf_ratio; 02009 sub_v3_v3v3(v0, p1, p0); 02010 sub_v3_v3v3(v1, p2, p0); 02011 cross_v3_v3v3(norm, v0, v1); 02012 02013 f2x_surf_area = len_v3(norm); 02014 fsurf_ratio = f2x_surf_area/f2x_area_uv; // tri area divided by texture area 02015 02016 ++nr_accumulated; 02017 dsum += (double)(fsurf_ratio); 02018 } 02019 } 02020 } 02021 } 02022 } 02023 } 02024 02025 // finalize 02026 { 02027 const float avg_area_ratio = (nr_accumulated>0) ? ((float)(dsum / nr_accumulated)) : 1.0f; 02028 const float use_as_render_bump_scale = sqrtf(avg_area_ratio); // use width of average surface ratio as your bump scale 02029 dm->auto_bump_scale = use_as_render_bump_scale; 02030 } 02031 } 02032 else 02033 { 02034 dm->auto_bump_scale = 1.0f; 02035 } 02036 } 02037 02038 void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs) 02039 { 02040 CustomData *vdata, *fdata, *tfdata = NULL; 02041 int a, b, layer; 02042 02043 /* From the layers requested by the GLSL shader, figure out which ones are 02044 * actually available for this derivedmesh, and retrieve the pointers */ 02045 02046 memset(attribs, 0, sizeof(DMVertexAttribs)); 02047 02048 vdata = &dm->vertData; 02049 fdata = &dm->faceData; 02050 02051 /* ugly hack, editmesh derivedmesh doesn't copy face data, this way we 02052 * can use offsets instead */ 02053 if(dm->type == DM_TYPE_EDITMESH) 02054 tfdata = &((EditMeshDerivedMesh*)dm)->em->fdata; 02055 else 02056 tfdata = fdata; 02057 02058 /* calc auto bump scale if necessary */ 02059 if(dm->auto_bump_scale<=0.0f) 02060 DM_calc_auto_bump_scale(dm); 02061 02062 /* add a tangent layer if necessary */ 02063 for(b = 0; b < gattribs->totlayer; b++) 02064 if(gattribs->layer[b].type == CD_TANGENT) 02065 if(CustomData_get_layer_index(fdata, CD_TANGENT) == -1) 02066 DM_add_tangent_layer(dm); 02067 02068 for(b = 0; b < gattribs->totlayer; b++) { 02069 if(gattribs->layer[b].type == CD_MTFACE) { 02070 /* uv coordinates */ 02071 if(gattribs->layer[b].name[0]) 02072 layer = CustomData_get_named_layer_index(tfdata, CD_MTFACE, 02073 gattribs->layer[b].name); 02074 else 02075 layer = CustomData_get_active_layer_index(tfdata, CD_MTFACE); 02076 02077 if(layer != -1) { 02078 a = attribs->tottface++; 02079 02080 attribs->tface[a].array = tfdata->layers[layer].data; 02081 attribs->tface[a].emOffset = tfdata->layers[layer].offset; 02082 attribs->tface[a].glIndex = gattribs->layer[b].glindex; 02083 attribs->tface[a].glTexco = gattribs->layer[b].gltexco; 02084 } 02085 } 02086 else if(gattribs->layer[b].type == CD_MCOL) { 02087 /* vertex colors */ 02088 if(gattribs->layer[b].name[0]) 02089 layer = CustomData_get_named_layer_index(tfdata, CD_MCOL, 02090 gattribs->layer[b].name); 02091 else 02092 layer = CustomData_get_active_layer_index(tfdata, CD_MCOL); 02093 02094 if(layer != -1) { 02095 a = attribs->totmcol++; 02096 02097 attribs->mcol[a].array = tfdata->layers[layer].data; 02098 attribs->mcol[a].emOffset = tfdata->layers[layer].offset; 02099 attribs->mcol[a].glIndex = gattribs->layer[b].glindex; 02100 } 02101 } 02102 else if(gattribs->layer[b].type == CD_TANGENT) { 02103 /* tangents */ 02104 layer = CustomData_get_layer_index(fdata, CD_TANGENT); 02105 02106 if(layer != -1) { 02107 attribs->tottang = 1; 02108 02109 attribs->tang.array = fdata->layers[layer].data; 02110 attribs->tang.emOffset = fdata->layers[layer].offset; 02111 attribs->tang.glIndex = gattribs->layer[b].glindex; 02112 } 02113 } 02114 else if(gattribs->layer[b].type == CD_ORCO) { 02115 /* original coordinates */ 02116 layer = CustomData_get_layer_index(vdata, CD_ORCO); 02117 02118 if(layer != -1) { 02119 attribs->totorco = 1; 02120 02121 attribs->orco.array = vdata->layers[layer].data; 02122 attribs->orco.emOffset = vdata->layers[layer].offset; 02123 attribs->orco.glIndex = gattribs->layer[b].glindex; 02124 attribs->orco.glTexco = gattribs->layer[b].gltexco; 02125 } 02126 } 02127 } 02128 } 02129 02130 /* Set object's bounding box based on DerivedMesh min/max data */ 02131 void DM_set_object_boundbox(Object *ob, DerivedMesh *dm) 02132 { 02133 float min[3], max[3]; 02134 02135 INIT_MINMAX(min, max); 02136 02137 dm->getMinMax(dm, min, max); 02138 02139 if(!ob->bb) 02140 ob->bb= MEM_callocN(sizeof(BoundBox), "DM-BoundBox"); 02141 02142 boundbox_set_from_min_max(ob->bb, min, max); 02143 } 02144 02145 /* --- NAVMESH (begin) --- */ 02146 #ifdef WITH_GAMEENGINE 02147 02148 BM_INLINE int navmesh_bit(int a, int b) 02149 { 02150 return (a & (1 << b)) >> b; 02151 } 02152 02153 BM_INLINE void navmesh_intToCol(int i, float col[3]) 02154 { 02155 int r = navmesh_bit(i, 0) + navmesh_bit(i, 3) * 2 + 1; 02156 int g = navmesh_bit(i, 1) + navmesh_bit(i, 4) * 2 + 1; 02157 int b = navmesh_bit(i, 2) + navmesh_bit(i, 5) * 2 + 1; 02158 col[0] = 1 - r*63.0f/255.0f; 02159 col[1] = 1 - g*63.0f/255.0f; 02160 col[2] = 1 - b*63.0f/255.0f; 02161 } 02162 02163 static void navmesh_drawColored(DerivedMesh *dm) 02164 { 02165 int a, glmode; 02166 MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT); 02167 MFace *mface = (MFace *)CustomData_get_layer(&dm->faceData, CD_MFACE); 02168 int *polygonIdx = (int *)CustomData_get_layer(&dm->faceData, CD_RECAST); 02169 float col[3]; 02170 02171 if (!polygonIdx) 02172 return; 02173 02174 /* 02175 //UI_ThemeColor(TH_WIRE); 02176 glDisable(GL_LIGHTING); 02177 glLineWidth(2.0); 02178 dm->drawEdges(dm, 0, 1); 02179 glLineWidth(1.0); 02180 glEnable(GL_LIGHTING);*/ 02181 02182 glDisable(GL_LIGHTING); 02183 /* if(GPU_buffer_legacy(dm) ) */ { /* TODO - VBO draw code, not high priority - campbell */ 02184 DEBUG_VBO( "Using legacy code. drawNavMeshColored\n" ); 02185 //glShadeModel(GL_SMOOTH); 02186 glBegin(glmode = GL_QUADS); 02187 for(a = 0; a < dm->numFaceData; a++, mface++) { 02188 int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES; 02189 int pi = polygonIdx[a]; 02190 if (pi <= 0) { 02191 zero_v3(col); 02192 } 02193 else { 02194 navmesh_intToCol(pi, col); 02195 } 02196 02197 if(new_glmode != glmode) { 02198 glEnd(); 02199 glBegin(glmode = new_glmode); 02200 } 02201 glColor3fv(col); 02202 glVertex3fv(mvert[mface->v1].co); 02203 glVertex3fv(mvert[mface->v2].co); 02204 glVertex3fv(mvert[mface->v3].co); 02205 if(mface->v4) { 02206 glVertex3fv(mvert[mface->v4].co); 02207 } 02208 } 02209 glEnd(); 02210 } 02211 glEnable(GL_LIGHTING); 02212 } 02213 02214 static void navmesh_DM_drawFacesTex(DerivedMesh *dm, 02215 int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr), 02216 int (*compareDrawOptions)(void *userData, int cur_index, int next_index), 02217 void *userData) 02218 { 02219 (void) setDrawOptions; 02220 (void) compareDrawOptions; 02221 (void) userData; 02222 02223 navmesh_drawColored(dm); 02224 } 02225 02226 static void navmesh_DM_drawFacesSolid(DerivedMesh *dm, 02227 float (*partial_redraw_planes)[4], 02228 int UNUSED(fast), int (*setMaterial)(int, void *attribs)) 02229 { 02230 (void) partial_redraw_planes; 02231 (void) setMaterial; 02232 02233 //drawFacesSolid_original(dm, partial_redraw_planes, fast, setMaterial); 02234 navmesh_drawColored(dm); 02235 } 02236 02237 static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm) 02238 { 02239 DerivedMesh *result; 02240 int maxFaces = dm->getNumFaces(dm); 02241 int *recastData; 02242 int vertsPerPoly=0, nverts=0, ndtris=0, npolys=0; 02243 float* verts=NULL; 02244 unsigned short *dtris=NULL, *dmeshes=NULL, *polys=NULL; 02245 int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL; 02246 int res; 02247 02248 result = CDDM_copy(dm); 02249 if (!CustomData_has_layer(&result->faceData, CD_RECAST)) { 02250 int *sourceRecastData = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); 02251 if (sourceRecastData) { 02252 CustomData_add_layer_named(&result->faceData, CD_RECAST, CD_DUPLICATE, 02253 sourceRecastData, maxFaces, "recastData"); 02254 } 02255 } 02256 recastData = (int*)CustomData_get_layer(&result->faceData, CD_RECAST); 02257 02258 /* note: This is not good design! - really should not be doing this */ 02259 result->drawFacesTex = navmesh_DM_drawFacesTex; 02260 result->drawFacesSolid = navmesh_DM_drawFacesSolid; 02261 02262 02263 /* process mesh */ 02264 res = buildNavMeshDataByDerivedMesh(dm, &vertsPerPoly, &nverts, &verts, &ndtris, &dtris, 02265 &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap, 02266 &trisToFacesMap); 02267 if (res) { 02268 size_t polyIdx; 02269 02270 /* invalidate concave polygon */ 02271 for (polyIdx=0; polyIdx<(size_t)npolys; polyIdx++) { 02272 unsigned short* poly = &polys[polyIdx*2*vertsPerPoly]; 02273 if (!polyIsConvex(poly, vertsPerPoly, verts)) { 02274 /* set negative polygon idx to all faces */ 02275 unsigned short *dmesh = &dmeshes[4*polyIdx]; 02276 unsigned short tbase = dmesh[2]; 02277 unsigned short tnum = dmesh[3]; 02278 unsigned short ti; 02279 02280 for (ti=0; ti<tnum; ti++) { 02281 unsigned short triidx = dtrisToTrisMap[tbase+ti]; 02282 unsigned short faceidx = trisToFacesMap[triidx]; 02283 if (recastData[faceidx] > 0) { 02284 recastData[faceidx] = -recastData[faceidx]; 02285 } 02286 } 02287 } 02288 } 02289 } 02290 else { 02291 printf("Error during creation polygon infos\n"); 02292 } 02293 02294 /* clean up */ 02295 if (verts!=NULL) 02296 MEM_freeN(verts); 02297 if (dtris!=NULL) 02298 MEM_freeN(dtris); 02299 if (dmeshes!=NULL) 02300 MEM_freeN(dmeshes); 02301 if (polys!=NULL) 02302 MEM_freeN(polys); 02303 if (dtrisToPolysMap!=NULL) 02304 MEM_freeN(dtrisToPolysMap); 02305 if (dtrisToTrisMap!=NULL) 02306 MEM_freeN(dtrisToTrisMap); 02307 if (trisToFacesMap!=NULL) 02308 MEM_freeN(trisToFacesMap); 02309 02310 return result; 02311 } 02312 02313 #endif /* WITH_GAMEENGINE */ 02314 02315 /* --- NAVMESH (end) --- */