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) 2011 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * ***** END GPL LICENSE BLOCK ***** 00022 */ 00023 00029 #include <stdio.h> 00030 #include <stdlib.h> 00031 #include <string.h> 00032 #include <limits.h> 00033 00034 #include "DNA_mesh_types.h" 00035 #include "DNA_meshdata_types.h" 00036 00037 #include "BLO_sys_types.h" 00038 00039 #include "BLI_utildefines.h" 00040 #include "BLI_edgehash.h" 00041 #include "BLI_math_base.h" 00042 00043 #include "BKE_DerivedMesh.h" 00044 00045 #include "MEM_guardedalloc.h" 00046 00047 #include "BKE_mesh.h" 00048 #include "BKE_deform.h" 00049 00050 #define SELECT 1 00051 00052 typedef union { 00053 uint32_t verts[2]; 00054 int64_t edval; 00055 } EdgeUUID; 00056 00057 typedef struct SortFace { 00058 // unsigned int v[4]; 00059 EdgeUUID es[4]; 00060 unsigned int index; 00061 } SortFace; 00062 00063 static void edge_store_assign(uint32_t verts[2], const uint32_t v1, const uint32_t v2) 00064 { 00065 if(v1 < v2) { 00066 verts[0]= v1; 00067 verts[1]= v2; 00068 } 00069 else { 00070 verts[0]= v2; 00071 verts[1]= v1; 00072 } 00073 } 00074 00075 static void edge_store_from_mface_quad(EdgeUUID es[4], MFace *mf) 00076 { 00077 edge_store_assign(es[0].verts, mf->v1, mf->v2); 00078 edge_store_assign(es[1].verts, mf->v2, mf->v3); 00079 edge_store_assign(es[2].verts, mf->v3, mf->v4); 00080 edge_store_assign(es[3].verts, mf->v4, mf->v1); 00081 } 00082 00083 static void edge_store_from_mface_tri(EdgeUUID es[4], MFace *mf) 00084 { 00085 edge_store_assign(es[0].verts, mf->v1, mf->v2); 00086 edge_store_assign(es[1].verts, mf->v2, mf->v3); 00087 edge_store_assign(es[2].verts, mf->v3, mf->v1); 00088 es[3].verts[0] = es[3].verts[1] = UINT_MAX; 00089 } 00090 00091 static int int64_cmp(const void *v1, const void *v2) 00092 { 00093 const int64_t x1= *(const int64_t *)v1; 00094 const int64_t x2= *(const int64_t *)v2; 00095 00096 if( x1 > x2 ) return 1; 00097 else if( x1 < x2 ) return -1; 00098 return 0; 00099 } 00100 00101 static int search_face_cmp(const void *v1, const void *v2) 00102 { 00103 const SortFace *sfa= v1, *sfb= v2; 00104 00105 if (sfa->es[0].edval > sfb->es[0].edval) return 1; 00106 else if (sfa->es[0].edval < sfb->es[0].edval) return -1; 00107 00108 else if (sfa->es[1].edval > sfb->es[1].edval) return 1; 00109 else if (sfa->es[1].edval < sfb->es[1].edval) return -1; 00110 00111 else if (sfa->es[2].edval > sfb->es[2].edval) return 1; 00112 else if (sfa->es[2].edval < sfb->es[2].edval) return -1; 00113 00114 else if (sfa->es[3].edval > sfb->es[3].edval) return 1; 00115 else if (sfa->es[3].edval < sfb->es[3].edval) return -1; 00116 else return 0; 00117 00118 } 00119 00120 #define PRINT if(do_verbose) printf 00121 00122 int BKE_mesh_validate_arrays( Mesh *me, 00123 MVert *mverts, unsigned int totvert, 00124 MEdge *medges, unsigned int totedge, 00125 MFace *mfaces, unsigned int totface, 00126 MDeformVert *dverts, /* assume totvert length */ 00127 const short do_verbose, const short do_fixes) 00128 { 00129 # define REMOVE_EDGE_TAG(_med) { _med->v2= _med->v1; do_edge_free= 1; } 00130 # define REMOVE_FACE_TAG(_mf) { _mf->v3=0; do_face_free= 1; } 00131 00132 // MVert *mv; 00133 MEdge *med; 00134 MFace *mf; 00135 MFace *mf_prev; 00136 MVert *mvert= mverts; 00137 unsigned int i; 00138 00139 short do_face_free= FALSE; 00140 short do_edge_free= FALSE; 00141 00142 short verts_fixed= FALSE; 00143 short vert_weights_fixed= FALSE; 00144 00145 int do_edge_recalc= FALSE; 00146 00147 EdgeHash *edge_hash = BLI_edgehash_new(); 00148 00149 SortFace *sort_faces= MEM_callocN(sizeof(SortFace) * totface, "search faces"); 00150 SortFace *sf; 00151 SortFace *sf_prev; 00152 unsigned int totsortface= 0; 00153 00154 BLI_assert(!(do_fixes && me == NULL)); 00155 00156 PRINT("%s: verts(%u), edges(%u), faces(%u)\n", __func__, totvert, totedge, totface); 00157 00158 if(totedge == 0 && totface != 0) { 00159 PRINT(" locical error, %u faces and 0 edges\n", totface); 00160 do_edge_recalc= TRUE; 00161 } 00162 00163 for(i=1; i<totvert; i++, mvert++) { 00164 int j; 00165 int fix_normal= TRUE; 00166 00167 for(j=0; j<3; j++) { 00168 if(!finite(mvert->co[j])) { 00169 PRINT(" vertex %u: has invalid coordinate\n", i); 00170 00171 if (do_fixes) { 00172 zero_v3(mvert->co); 00173 00174 verts_fixed= TRUE; 00175 } 00176 } 00177 00178 if(mvert->no[j]!=0) 00179 fix_normal= FALSE; 00180 } 00181 00182 if(fix_normal) { 00183 PRINT(" vertex %u: has zero normal, assuming Z-up normal\n", i); 00184 if (do_fixes) { 00185 mvert->no[2]= SHRT_MAX; 00186 verts_fixed= TRUE; 00187 } 00188 } 00189 } 00190 00191 for(i=0, med= medges; i<totedge; i++, med++) { 00192 int remove= FALSE; 00193 if(med->v1 == med->v2) { 00194 PRINT(" edge %u: has matching verts, both %u\n", i, med->v1); 00195 remove= do_fixes; 00196 } 00197 if(med->v1 >= totvert) { 00198 PRINT(" edge %u: v1 index out of range, %u\n", i, med->v1); 00199 remove= do_fixes; 00200 } 00201 if(med->v2 >= totvert) { 00202 PRINT(" edge %u: v2 index out of range, %u\n", i, med->v2); 00203 remove= do_fixes; 00204 } 00205 00206 if(BLI_edgehash_haskey(edge_hash, med->v1, med->v2)) { 00207 PRINT(" edge %u: is a duplicate of, %d\n", i, GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, med->v1, med->v2))); 00208 remove= do_fixes; 00209 } 00210 00211 if(remove == FALSE){ 00212 BLI_edgehash_insert(edge_hash, med->v1, med->v2, SET_INT_IN_POINTER(i)); 00213 } 00214 else { 00215 REMOVE_EDGE_TAG(med); 00216 } 00217 } 00218 00219 for(i=0, mf=mfaces, sf=sort_faces; i<totface; i++, mf++) { 00220 int remove= FALSE; 00221 int fidx; 00222 unsigned int fv[4]; 00223 00224 fidx = mf->v4 ? 3:2; 00225 do { 00226 fv[fidx]= *(&(mf->v1) + fidx); 00227 if(fv[fidx] >= totvert) { 00228 PRINT(" face %u: 'v%d' index out of range, %u\n", i, fidx + 1, fv[fidx]); 00229 remove= do_fixes; 00230 } 00231 } while (fidx--); 00232 00233 if(remove == FALSE) { 00234 if(mf->v4) { 00235 if(mf->v1 == mf->v2) { PRINT(" face %u: verts invalid, v1/v2 both %u\n", i, mf->v1); remove= do_fixes; } 00236 if(mf->v1 == mf->v3) { PRINT(" face %u: verts invalid, v1/v3 both %u\n", i, mf->v1); remove= do_fixes; } 00237 if(mf->v1 == mf->v4) { PRINT(" face %u: verts invalid, v1/v4 both %u\n", i, mf->v1); remove= do_fixes; } 00238 00239 if(mf->v2 == mf->v3) { PRINT(" face %u: verts invalid, v2/v3 both %u\n", i, mf->v2); remove= do_fixes; } 00240 if(mf->v2 == mf->v4) { PRINT(" face %u: verts invalid, v2/v4 both %u\n", i, mf->v2); remove= do_fixes; } 00241 00242 if(mf->v3 == mf->v4) { PRINT(" face %u: verts invalid, v3/v4 both %u\n", i, mf->v3); remove= do_fixes; } 00243 } 00244 else { 00245 if(mf->v1 == mf->v2) { PRINT(" faceT %u: verts invalid, v1/v2 both %u\n", i, mf->v1); remove= do_fixes; } 00246 if(mf->v1 == mf->v3) { PRINT(" faceT %u: verts invalid, v1/v3 both %u\n", i, mf->v1); remove= do_fixes; } 00247 00248 if(mf->v2 == mf->v3) { PRINT(" faceT %u: verts invalid, v2/v3 both %u\n", i, mf->v2); remove= do_fixes; } 00249 } 00250 00251 if(remove == FALSE) { 00252 if(totedge) { 00253 if(mf->v4) { 00254 if(!BLI_edgehash_haskey(edge_hash, mf->v1, mf->v2)) { PRINT(" face %u: edge v1/v2 (%u,%u) is missing egde data\n", i, mf->v1, mf->v2); do_edge_recalc= TRUE; } 00255 if(!BLI_edgehash_haskey(edge_hash, mf->v2, mf->v3)) { PRINT(" face %u: edge v2/v3 (%u,%u) is missing egde data\n", i, mf->v2, mf->v3); do_edge_recalc= TRUE; } 00256 if(!BLI_edgehash_haskey(edge_hash, mf->v3, mf->v4)) { PRINT(" face %u: edge v3/v4 (%u,%u) is missing egde data\n", i, mf->v3, mf->v4); do_edge_recalc= TRUE; } 00257 if(!BLI_edgehash_haskey(edge_hash, mf->v4, mf->v1)) { PRINT(" face %u: edge v4/v1 (%u,%u) is missing egde data\n", i, mf->v4, mf->v1); do_edge_recalc= TRUE; } 00258 } 00259 else { 00260 if(!BLI_edgehash_haskey(edge_hash, mf->v1, mf->v2)) { PRINT(" face %u: edge v1/v2 (%u,%u) is missing egde data\n", i, mf->v1, mf->v2); do_edge_recalc= TRUE; } 00261 if(!BLI_edgehash_haskey(edge_hash, mf->v2, mf->v3)) { PRINT(" face %u: edge v2/v3 (%u,%u) is missing egde data\n", i, mf->v2, mf->v3); do_edge_recalc= TRUE; } 00262 if(!BLI_edgehash_haskey(edge_hash, mf->v3, mf->v1)) { PRINT(" face %u: edge v3/v1 (%u,%u) is missing egde data\n", i, mf->v3, mf->v1); do_edge_recalc= TRUE; } 00263 } 00264 } 00265 00266 sf->index = i; 00267 00268 if(mf->v4) { 00269 edge_store_from_mface_quad(sf->es, mf); 00270 00271 qsort(sf->es, 4, sizeof(int64_t), int64_cmp); 00272 } 00273 else { 00274 edge_store_from_mface_tri(sf->es, mf); 00275 qsort(sf->es, 3, sizeof(int64_t), int64_cmp); 00276 } 00277 00278 totsortface++; 00279 sf++; 00280 } 00281 } 00282 if(remove) { 00283 REMOVE_FACE_TAG(mf); 00284 } 00285 } 00286 00287 qsort(sort_faces, totsortface, sizeof(SortFace), search_face_cmp); 00288 00289 sf= sort_faces; 00290 sf_prev= sf; 00291 sf++; 00292 00293 for(i=1; i<totsortface; i++, sf++) { 00294 int remove= FALSE; 00295 /* on a valid mesh, code below will never run */ 00296 if(memcmp(sf->es, sf_prev->es, sizeof(sf_prev->es)) == 0) { 00297 mf= mfaces + sf->index; 00298 00299 if(do_verbose) { 00300 mf_prev= mfaces + sf_prev->index; 00301 if(mf->v4) { 00302 PRINT(" face %u & %u: are duplicates (%u,%u,%u,%u) (%u,%u,%u,%u)\n", sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3, mf->v4, mf_prev->v1, mf_prev->v2, mf_prev->v3, mf_prev->v4); 00303 } 00304 else { 00305 PRINT(" face %u & %u: are duplicates (%u,%u,%u) (%u,%u,%u)\n", sf->index, sf_prev->index, mf->v1, mf->v2, mf->v3, mf_prev->v1, mf_prev->v2, mf_prev->v3); 00306 } 00307 } 00308 00309 remove= do_fixes; 00310 } 00311 else { 00312 sf_prev= sf; 00313 } 00314 00315 if(remove) { 00316 REMOVE_FACE_TAG(mf); 00317 } 00318 } 00319 00320 BLI_edgehash_free(edge_hash, NULL); 00321 MEM_freeN(sort_faces); 00322 00323 00324 /* fix deform verts */ 00325 if (dverts) { 00326 MDeformVert *dv; 00327 for(i=0, dv= dverts; i<totvert; i++, dv++) { 00328 MDeformWeight *dw; 00329 unsigned int j; 00330 00331 for(j=0, dw= dv->dw; j < dv->totweight; j++, dw++) { 00332 /* note, greater then max defgroups is accounted for in our code, but not < 0 */ 00333 if (!finite(dw->weight)) { 00334 PRINT(" vertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight); 00335 if (do_fixes) { 00336 dw->weight= 0.0f; 00337 vert_weights_fixed= TRUE; 00338 } 00339 } 00340 else if (dw->weight < 0.0f || dw->weight > 1.0f) { 00341 PRINT(" vertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight); 00342 if (do_fixes) { 00343 CLAMP(dw->weight, 0.0f, 1.0f); 00344 vert_weights_fixed= TRUE; 00345 } 00346 } 00347 00348 if (dw->def_nr < 0) { 00349 PRINT(" vertex deform %u, has invalid group %d\n", i, dw->def_nr); 00350 if (do_fixes) { 00351 defvert_remove_group(dv, dw); 00352 if (dv->dw) { 00353 /* re-allocated, the new values compensate for stepping 00354 * within the for loop and may not be valid */ 00355 j--; 00356 dw= dv->dw + j; 00357 00358 vert_weights_fixed= TRUE; 00359 } 00360 else { /* all freed */ 00361 break; 00362 } 00363 } 00364 } 00365 } 00366 } 00367 } 00368 00369 00370 PRINT("BKE_mesh_validate: finished\n\n"); 00371 00372 # undef REMOVE_EDGE_TAG 00373 # undef REMOVE_FACE_TAG 00374 00375 if(me) { 00376 if(do_face_free) { 00377 mesh_strip_loose_faces(me); 00378 } 00379 00380 if (do_edge_free) { 00381 mesh_strip_loose_edges(me); 00382 } 00383 00384 if(do_fixes && do_edge_recalc) { 00385 BKE_mesh_calc_edges(me, TRUE); 00386 } 00387 } 00388 00389 return (verts_fixed || vert_weights_fixed || do_face_free || do_edge_free || do_edge_recalc); 00390 } 00391 00392 static int mesh_validate_customdata(CustomData *data, short do_verbose, const short do_fixes) 00393 { 00394 int i= 0, has_fixes= 0; 00395 00396 while(i<data->totlayer) { 00397 CustomDataLayer *layer= &data->layers[i]; 00398 CustomDataMask mask= CD_TYPE_AS_MASK(layer->type); 00399 int ok= 1; 00400 00401 if((mask&CD_MASK_MESH)==0) { 00402 PRINT("CustomDataLayer type %d which isn't in CD_MASK_MESH is stored in Mehs structure\n", layer->type); 00403 00404 if(do_fixes) { 00405 CustomData_free_layer(data, layer->type, 0, i); 00406 ok= 0; 00407 has_fixes= 1; 00408 } 00409 } 00410 00411 if(ok) 00412 i++; 00413 } 00414 00415 return has_fixes; 00416 } 00417 00418 #undef PRINT 00419 00420 static int BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata, CustomData *fdata, 00421 short do_verbose, const short do_fixes) 00422 { 00423 int vfixed= 0, efixed= 0, ffixed= 0; 00424 00425 vfixed= mesh_validate_customdata(vdata, do_verbose, do_fixes); 00426 efixed= mesh_validate_customdata(edata, do_verbose, do_fixes); 00427 ffixed= mesh_validate_customdata(fdata, do_verbose, do_fixes); 00428 00429 return vfixed || efixed || ffixed; 00430 } 00431 00432 int BKE_mesh_validate(Mesh *me, int do_verbose) 00433 { 00434 int layers_fixed= 0, arrays_fixed= 0; 00435 00436 if(do_verbose) { 00437 printf("MESH: %s\n", me->id.name+2); 00438 } 00439 00440 layers_fixed= BKE_mesh_validate_all_customdata(&me->vdata, &me->edata, &me->fdata, do_verbose, TRUE); 00441 arrays_fixed= BKE_mesh_validate_arrays(me, 00442 me->mvert, me->totvert, 00443 me->medge, me->totedge, 00444 me->mface, me->totface, 00445 me->dvert, 00446 do_verbose, TRUE); 00447 00448 return layers_fixed || arrays_fixed; 00449 } 00450 00451 int BKE_mesh_validate_dm(DerivedMesh *dm) 00452 { 00453 return BKE_mesh_validate_arrays(NULL, 00454 dm->getVertArray(dm), dm->getNumVerts(dm), 00455 dm->getEdgeArray(dm), dm->getNumEdges(dm), 00456 dm->getFaceArray(dm), dm->getNumFaces(dm), 00457 dm->getVertDataArray(dm, CD_MDEFORMVERT), 00458 TRUE, FALSE); 00459 } 00460 00461 void BKE_mesh_calc_edges(Mesh *mesh, int update) 00462 { 00463 CustomData edata; 00464 EdgeHashIterator *ehi; 00465 MFace *mf = mesh->mface; 00466 MEdge *med, *med_orig; 00467 EdgeHash *eh = BLI_edgehash_new(); 00468 int i, totedge, totface = mesh->totface; 00469 00470 if(mesh->totedge==0) 00471 update= 0; 00472 00473 if(update) { 00474 /* assume existing edges are valid 00475 * useful when adding more faces and generating edges from them */ 00476 med= mesh->medge; 00477 for(i= 0; i<mesh->totedge; i++, med++) 00478 BLI_edgehash_insert(eh, med->v1, med->v2, med); 00479 } 00480 00481 for (i = 0; i < totface; i++, mf++) { 00482 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2)) 00483 BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL); 00484 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3)) 00485 BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL); 00486 00487 if (mf->v4) { 00488 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4)) 00489 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL); 00490 if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1)) 00491 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL); 00492 } else { 00493 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1)) 00494 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL); 00495 } 00496 } 00497 00498 totedge = BLI_edgehash_size(eh); 00499 00500 /* write new edges into a temporary CustomData */ 00501 memset(&edata, 0, sizeof(edata)); 00502 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); 00503 00504 ehi = BLI_edgehashIterator_new(eh); 00505 med = CustomData_get_layer(&edata, CD_MEDGE); 00506 for(i = 0; !BLI_edgehashIterator_isDone(ehi); 00507 BLI_edgehashIterator_step(ehi), ++i, ++med) { 00508 00509 if(update && (med_orig=BLI_edgehashIterator_getValue(ehi))) { 00510 *med= *med_orig; /* copy from the original */ 00511 } else { 00512 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2); 00513 med->flag = ME_EDGEDRAW|ME_EDGERENDER|SELECT; /* select for newly created meshes which are selected [#25595] */ 00514 } 00515 } 00516 BLI_edgehashIterator_free(ehi); 00517 00518 /* free old CustomData and assign new one */ 00519 CustomData_free(&mesh->edata, mesh->totedge); 00520 mesh->edata = edata; 00521 mesh->totedge = totedge; 00522 00523 mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE); 00524 00525 BLI_edgehash_free(eh, NULL); 00526 }