MOAB: Mesh Oriented datABase
(version 5.3.1)
|
00001 #include <vector> 00002 #include <utility> 00003 #include <iostream> 00004 using namespace std; 00005 using namespace moab; 00006 00007 #include "moab/Core.hpp" 00008 #include "moab/Interface.hpp" 00009 #include "moab/Range.hpp" 00010 00011 Interface* gMB = 0; 00012 00013 class EntityCount 00014 { 00015 public: 00016 unsigned int node; 00017 unsigned int edge; 00018 unsigned int quad; 00019 unsigned int tri; 00020 unsigned int hex; 00021 unsigned int tet; 00022 00023 EntityCount(); 00024 00025 ErrorCode get_counts(); 00026 ErrorCode create_adjacencies( Range& entities, int adj_dim ); 00027 void copy_counts( EntityCount& count ); 00028 void print(); 00029 }; 00030 00031 EntityCount::EntityCount() 00032 { 00033 node = 0; 00034 edge = 0; 00035 quad = 0; 00036 tri = 0; 00037 hex = 0; 00038 tet = 0; 00039 } 00040 00041 void EntityCount::copy_counts( EntityCount& count ) 00042 { 00043 node = count.node; 00044 edge = count.edge; 00045 quad = count.quad; 00046 tri = count.tri; 00047 hex = count.hex; 00048 tet = count.tet; 00049 } 00050 00051 ErrorCode EntityCount::get_counts() 00052 { 00053 Range entities; 00054 int do_create = edge == 0; 00055 00056 if( gMB->get_entities_by_type( 0, MBVERTEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00057 node = entities.size(); 00058 00059 entities.clear(); 00060 if( gMB->get_entities_by_type( 0, MBHEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00061 hex = entities.size(); 00062 if( hex > 0 && do_create ) 00063 { 00064 if( create_adjacencies( entities, 2 ) != MB_SUCCESS ) return MB_FAILURE; 00065 if( create_adjacencies( entities, 1 ) != MB_SUCCESS ) return MB_FAILURE; 00066 } 00067 00068 entities.clear(); 00069 if( gMB->get_entities_by_type( 0, MBQUAD, entities ) != MB_SUCCESS ) return MB_FAILURE; 00070 quad = entities.size(); 00071 if( quad > 0 && do_create ) 00072 { 00073 00074 if( create_adjacencies( entities, 1 ) != MB_SUCCESS ) return MB_FAILURE; 00075 } 00076 00077 entities.clear(); 00078 if( gMB->get_entities_by_type( 0, MBTET, entities ) != MB_SUCCESS ) return MB_FAILURE; 00079 tet = entities.size(); 00080 if( tet > 0 && do_create ) 00081 { 00082 if( create_adjacencies( entities, 2 ) != MB_SUCCESS ) return MB_FAILURE; 00083 if( create_adjacencies( entities, 1 ) != MB_SUCCESS ) return MB_FAILURE; 00084 } 00085 00086 entities.clear(); 00087 if( gMB->get_entities_by_type( 0, MBTRI, entities ) != MB_SUCCESS ) return MB_FAILURE; 00088 tri = entities.size(); 00089 if( tri > 0 && do_create ) 00090 { 00091 if( create_adjacencies( entities, 1 ) != MB_SUCCESS ) return MB_FAILURE; 00092 } 00093 00094 entities.clear(); 00095 if( gMB->get_entities_by_type( 0, MBEDGE, entities ) != MB_SUCCESS ) return MB_FAILURE; 00096 edge = entities.size(); 00097 00098 return MB_SUCCESS; 00099 } 00100 00101 ErrorCode EntityCount::create_adjacencies( Range& entities, int adj_dim ) 00102 { 00103 ErrorCode result; 00104 Range::iterator iter; 00105 std::vector< EntityHandle > adjacencies; 00106 00107 for( iter = entities.begin(); iter != entities.end(); ++iter ) 00108 { 00109 result = gMB->get_adjacencies( &*iter, 1, adj_dim, true, adjacencies ); 00110 if( result != MB_SUCCESS ) break; 00111 } 00112 00113 return result; 00114 } 00115 00116 void EntityCount::print() 00117 { 00118 std::cout << " Vertices: " << node << std::endl; 00119 cout << " Edges: " << edge << endl; 00120 if( quad > 0 ) cout << " Quad Elements: " << quad << endl; 00121 if( hex > 0 ) cout << " Hex Elements: " << hex << endl; 00122 if( tri > 0 ) cout << " Tri Elements: " << tri << endl; 00123 if( tet > 0 ) cout << " Tet Elements: " << tet << endl; 00124 } 00125 00126 bool points_are_coincident( const double* first, const double* second ) 00127 { 00128 double diff[3]; 00129 diff[0] = first[0] - second[0]; 00130 diff[1] = first[1] - second[1]; 00131 diff[2] = first[2] - second[2]; 00132 double length = diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2]; 00133 00134 if( fabs( length ) < .001 ) return true; 00135 00136 return false; 00137 } 00138 00139 // dumb n^2 coincident node algorithm 00140 ErrorCode find_coincident_nodes( Range vertices, std::vector< std::pair< EntityHandle, EntityHandle > >& coin_nodes ) 00141 { 00142 double first_coords[3], second_coords[3]; 00143 Range::iterator iter, jter; 00144 std::pair< EntityHandle, EntityHandle > coincident_pair; 00145 ErrorCode result; 00146 00147 for( iter = vertices.begin(); iter != vertices.end(); ++iter ) 00148 { 00149 result = gMB->get_coords( &*iter, 1, first_coords ); 00150 if( result != MB_SUCCESS ) return result; 00151 00152 for( jter = iter; jter != vertices.end(); ++jter ) 00153 { 00154 if( *iter != *jter ) 00155 { 00156 result = gMB->get_coords( &*jter, 1, second_coords ); 00157 if( result != MB_SUCCESS ) return result; 00158 00159 if( points_are_coincident( first_coords, second_coords ) ) 00160 { 00161 coincident_pair.first = *iter; 00162 coincident_pair.second = *jter; 00163 coin_nodes.push_back( coincident_pair ); 00164 } 00165 } 00166 } 00167 } 00168 return MB_SUCCESS; 00169 } 00170 00171 ErrorCode find_coincident_edges( Range entities, std::vector< std::pair< EntityHandle, EntityHandle > >& coin_edges ) 00172 { 00173 double coords1[3], coords2[3], coords3[3]; 00174 Range::iterator iter, jter; 00175 std::vector< EntityHandle > conn( 2 ); 00176 std::pair< EntityHandle, EntityHandle > coincident_pair; 00177 00178 for( iter = entities.begin(); iter != entities.end(); ++iter ) 00179 { 00180 if( gMB->get_connectivity( &*iter, 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 00181 00182 // Get the coordinates for the edge endpoints. 00183 if( gMB->get_coords( &conn[0], 1, coords1 ) != MB_SUCCESS ) return MB_FAILURE; 00184 00185 if( gMB->get_coords( &conn[1], 1, coords2 ) != MB_SUCCESS ) return MB_FAILURE; 00186 00187 for( jter = iter; jter != entities.end(); ++jter ) 00188 { 00189 if( *iter != *jter ) 00190 { 00191 // Edges should be the same sense to merge. 00192 if( gMB->get_connectivity( &*jter, 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 00193 00194 if( gMB->get_coords( &conn[0], 1, coords3 ) != MB_SUCCESS ) return MB_FAILURE; 00195 00196 if( points_are_coincident( coords1, coords3 ) ) 00197 { 00198 if( gMB->get_coords( &conn[1], 1, coords3 ) != MB_SUCCESS ) return MB_FAILURE; 00199 00200 if( points_are_coincident( coords2, coords3 ) ) 00201 { 00202 coincident_pair.first = *iter; 00203 coincident_pair.second = *jter; 00204 coin_edges.push_back( coincident_pair ); 00205 } 00206 } 00207 } 00208 } 00209 } 00210 00211 return MB_SUCCESS; 00212 } 00213 00214 ErrorCode find_coincident_elements( Range entities, int num_nodes, 00215 std::vector< std::pair< EntityHandle, EntityHandle > >& coin ) 00216 { 00217 double coords1[8][3], coords2[8][3]; 00218 Range::iterator iter, jter; 00219 std::vector< EntityHandle > conn( 8 ); 00220 std::pair< EntityHandle, EntityHandle > coincident_pair; 00221 int i = 0, j = 0, ii = 0; 00222 00223 for( iter = entities.begin(); iter != entities.end(); ++iter ) 00224 { 00225 // Get the coordinates for the element corners. 00226 if( gMB->get_connectivity( &*iter, 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 00227 for( ii = 0; ii < num_nodes; ii++ ) 00228 { 00229 if( gMB->get_coords( &conn[ii], 1, coords1[ii] ) != MB_SUCCESS ) return MB_FAILURE; 00230 } 00231 00232 for( jter = iter; jter != entities.end(); ++jter ) 00233 { 00234 if( *iter != *jter ) 00235 { 00236 // Elements should be the same sense to merge. 00237 if( gMB->get_connectivity( &*jter, 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 00238 00239 if( gMB->get_coords( &conn[0], 1, coords2[0] ) != MB_SUCCESS ) return MB_FAILURE; 00240 00241 // Find if first node is coincident before testing the rest. 00242 for( i = 0; i < num_nodes; i++ ) 00243 { 00244 if( points_are_coincident( coords1[i], coords2[0] ) ) break; 00245 } 00246 00247 if( i < num_nodes ) 00248 { 00249 for( ii = 1; ii < num_nodes; ii++ ) 00250 { 00251 if( gMB->get_coords( &conn[ii], 1, coords2[ii] ) != MB_SUCCESS ) return MB_FAILURE; 00252 } 00253 00254 for( j = 1; j < num_nodes; j++ ) 00255 { 00256 if( !points_are_coincident( coords1[j], coords2[( j + i ) % num_nodes] ) ) break; 00257 } 00258 00259 if( j == num_nodes ) 00260 00261 { 00262 coincident_pair.first = *iter; 00263 coincident_pair.second = *jter; 00264 coin.push_back( coincident_pair ); 00265 } 00266 } 00267 } 00268 } 00269 } 00270 00271 return MB_SUCCESS; 00272 } 00273 00274 ErrorCode coincident_counts( EntityCount& curr_count, EntityCount& diff_count ) 00275 { 00276 Range entities; 00277 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00278 00279 if( curr_count.node > 0 ) 00280 { 00281 if( gMB->get_entities_by_type( 0, MBVERTEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00282 find_coincident_nodes( entities, coincident ); 00283 diff_count.node = coincident.size(); 00284 entities.clear(); 00285 coincident.clear(); 00286 } 00287 if( curr_count.edge > 0 ) 00288 { 00289 if( gMB->get_entities_by_type( 0, MBEDGE, entities ) != MB_SUCCESS ) return MB_FAILURE; 00290 find_coincident_edges( entities, coincident ); 00291 diff_count.edge = coincident.size(); 00292 entities.clear(); 00293 coincident.clear(); 00294 } 00295 if( curr_count.quad > 0 ) 00296 { 00297 if( gMB->get_entities_by_type( 0, MBQUAD, entities ) != MB_SUCCESS ) return MB_FAILURE; 00298 find_coincident_elements( entities, 4, coincident ); 00299 diff_count.quad = coincident.size(); 00300 entities.clear(); 00301 coincident.clear(); 00302 } 00303 if( curr_count.tri > 0 ) 00304 { 00305 if( gMB->get_entities_by_type( 0, MBTRI, entities ) != MB_SUCCESS ) return MB_FAILURE; 00306 find_coincident_elements( entities, 3, coincident ); 00307 diff_count.tri = coincident.size(); 00308 entities.clear(); 00309 coincident.clear(); 00310 } 00311 if( curr_count.tet > 0 ) 00312 { 00313 if( gMB->get_entities_by_type( 0, MBTET, entities ) != MB_SUCCESS ) return MB_FAILURE; 00314 find_coincident_elements( entities, 4, coincident ); 00315 diff_count.tet = coincident.size(); 00316 entities.clear(); 00317 coincident.clear(); 00318 } 00319 if( curr_count.hex > 0 ) 00320 { 00321 if( gMB->get_entities_by_type( 0, MBHEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00322 find_coincident_elements( entities, 8, coincident ); 00323 diff_count.hex = coincident.size(); 00324 entities.clear(); 00325 coincident.clear(); 00326 } 00327 00328 return MB_SUCCESS; 00329 } 00330 00331 ErrorCode merge_top_down( EntityCount& init_count, EntityCount& curr_count ) 00332 { 00333 Range entities; 00334 EntityCount diff_count; 00335 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00336 00337 // Find how many objects of each type need to be merged. 00338 if( coincident_counts( curr_count, diff_count ) != MB_SUCCESS ) return MB_FAILURE; 00339 00340 // Find the top level object to merge. 00341 if( diff_count.hex > 0 ) 00342 { 00343 if( gMB->get_entities_by_type( 0, MBHEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00344 find_coincident_elements( entities, 8, coincident ); 00345 } 00346 else if( diff_count.quad > 0 ) 00347 { 00348 if( gMB->get_entities_by_type( 0, MBQUAD, entities ) != MB_SUCCESS ) return MB_FAILURE; 00349 find_coincident_elements( entities, 4, coincident ); 00350 } 00351 else if( diff_count.tet > 0 ) 00352 { 00353 if( gMB->get_entities_by_type( 0, MBTET, entities ) != MB_SUCCESS ) return MB_FAILURE; 00354 find_coincident_elements( entities, 4, coincident ); 00355 } 00356 else if( diff_count.tri > 0 ) 00357 00358 { 00359 if( gMB->get_entities_by_type( 0, MBTRI, entities ) != MB_SUCCESS ) return MB_FAILURE; 00360 find_coincident_elements( entities, 3, coincident ); 00361 } 00362 else if( diff_count.edge > 0 ) 00363 { 00364 if( gMB->get_entities_by_type( 0, MBEDGE, entities ) != MB_SUCCESS ) return MB_FAILURE; 00365 find_coincident_edges( entities, coincident ); 00366 } 00367 00368 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00369 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00370 gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00371 00372 // Get the new entity totals. 00373 curr_count.get_counts(); 00374 00375 // Make sure we didn't merge anything. 00376 if( init_count.node != curr_count.node || init_count.edge != curr_count.edge || 00377 init_count.quad != curr_count.quad || init_count.tri != curr_count.tri || init_count.hex != curr_count.hex || 00378 init_count.tet != curr_count.tet ) 00379 { 00380 cout << "***ERROR: Merged top down when not using auto merge.***" << endl; 00381 return MB_FAILURE; 00382 } 00383 00384 return MB_SUCCESS; 00385 } 00386 00387 ErrorCode merge_nodes( EntityCount& init_count, EntityCount& curr_count ) 00388 { 00389 cout << "Merging Coincident Nodes:" << endl; 00390 00391 // Get the list of vertices from the database. 00392 Range vertices; 00393 ErrorCode result = gMB->get_entities_by_type( 0, MBVERTEX, vertices ); 00394 if( result != MB_SUCCESS ) return result; 00395 00396 // find the coincident node pairs 00397 std::vector< std::pair< EntityHandle, EntityHandle > > coincident_nodes; 00398 find_coincident_nodes( vertices, coincident_nodes ); 00399 00400 // merge the coincident nodes 00401 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00402 for( iter = coincident_nodes.begin(); iter != coincident_nodes.end(); ++iter ) 00403 { 00404 cout << " Coincident nodes: " << ( *iter ).first << "-" << ( *iter ).second << endl; 00405 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00406 if( result != MB_SUCCESS ) return result; 00407 } 00408 00409 // Get the reduced list of vertices. 00410 curr_count.get_counts(); 00411 00412 // Make sure the coincident nodes were all merged. 00413 if( init_count.node - curr_count.node != coincident_nodes.size() ) 00414 { 00415 cout << "***ERROR: Not all coincident nodes were merged.***" << endl; 00416 return MB_FAILURE; 00417 } 00418 00419 init_count.node = curr_count.node; 00420 00421 // Make sure we didn't merge anything else. 00422 if( init_count.edge != curr_count.edge || init_count.quad != curr_count.quad || init_count.tri != curr_count.tri || 00423 init_count.hex != curr_count.hex || init_count.tet != curr_count.tet ) 00424 { 00425 cout << "***ERROR: Merged other objects when merging nodes.***" << endl; 00426 return MB_FAILURE; 00427 } 00428 00429 return MB_SUCCESS; 00430 } 00431 00432 ErrorCode merge_edges( EntityCount& init_count, EntityCount& curr_count ) 00433 { 00434 cout << "Merging Coincident Edges:" << endl; 00435 00436 // Get the list of entities from the database. 00437 Range entities; 00438 ErrorCode result = gMB->get_entities_by_type( 0, MBEDGE, entities ); 00439 if( result != MB_SUCCESS ) return result; 00440 00441 // find the coincident edge pairs 00442 std::vector< std::pair< EntityHandle, EntityHandle > > coincident_edges; 00443 find_coincident_edges( entities, coincident_edges ); 00444 00445 // merge the coincident edges 00446 unsigned long id1, id2; 00447 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00448 for( iter = coincident_edges.begin(); iter != coincident_edges.end(); ++iter ) 00449 { 00450 id1 = gMB->id_from_handle( ( *iter ).first ); 00451 id2 = gMB->id_from_handle( ( *iter ).second ); 00452 cout << " Coincident edges: " << id1 << "-" << id2 << endl; 00453 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00454 if( result != MB_SUCCESS ) return result; 00455 } 00456 00457 // Get the reduced list of edges. 00458 curr_count.get_counts(); 00459 00460 // Make sure the coincident edges were all merged. 00461 if( init_count.edge - curr_count.edge != coincident_edges.size() ) 00462 { 00463 cout << "***ERROR: Not all coincident edges were merged.***" << endl; 00464 return MB_FAILURE; 00465 } 00466 00467 init_count.edge = curr_count.edge; 00468 00469 // Make sure we didn't merge anything else. 00470 if( init_count.node != curr_count.node || init_count.quad != curr_count.quad || init_count.tri != curr_count.tri || 00471 init_count.hex != curr_count.hex || init_count.tet != curr_count.tet ) 00472 { 00473 cout << "***ERROR: Merged other objects when merging edges.***" << endl; 00474 return MB_FAILURE; 00475 } 00476 00477 return MB_SUCCESS; 00478 } 00479 00480 ErrorCode merge_2D_elem( EntityCount& init_count, EntityCount& curr_count ) 00481 { 00482 cout << "Merging Coincident 2D Elements:" << endl; 00483 00484 // Get the list of tris from the database. 00485 Range entities; 00486 ErrorCode result = gMB->get_entities_by_type( 0, MBTRI, entities ); 00487 if( result != MB_SUCCESS ) return result; 00488 00489 // find the coincident tri pairs 00490 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00491 find_coincident_elements( entities, 3, coincident ); 00492 00493 // merge the coincident tris 00494 unsigned long id1, id2; 00495 unsigned int tri_diff = coincident.size(); 00496 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00497 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00498 { 00499 id1 = gMB->id_from_handle( ( *iter ).first ); 00500 id2 = gMB->id_from_handle( ( *iter ).second ); 00501 cout << " Coincident tris: " << id1 << "-" << id2 << endl; 00502 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00503 00504 if( result != MB_SUCCESS ) return result; 00505 } 00506 00507 // Get the list of quads from the database. 00508 entities.clear(); 00509 result = gMB->get_entities_by_type( 0, MBQUAD, entities ); 00510 if( result != MB_SUCCESS ) return result; 00511 00512 // find the coincident tri pairs 00513 coincident.clear(); 00514 find_coincident_elements( entities, 4, coincident ); 00515 00516 // merge the coincident tris 00517 unsigned int quad_diff = coincident.size(); 00518 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00519 { 00520 id1 = gMB->id_from_handle( ( *iter ).first ); 00521 id2 = gMB->id_from_handle( ( *iter ).second ); 00522 cout << " Coincident quads: " << id1 << "-" << id2 << endl; 00523 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00524 if( result != MB_SUCCESS ) return result; 00525 } 00526 00527 // Get the reduced list of faces. 00528 curr_count.get_counts(); 00529 00530 // Make sure the coincident faces were all merged. 00531 if( init_count.tri - curr_count.tri != tri_diff ) 00532 { 00533 cout << "***ERROR: Not all coincident tris were merged.***" << endl; 00534 return MB_FAILURE; 00535 } 00536 if( init_count.quad - curr_count.quad != quad_diff ) 00537 { 00538 cout << "***ERROR: Not all coincident quads were merged.***" << endl; 00539 return MB_FAILURE; 00540 } 00541 00542 init_count.tri = curr_count.tri; 00543 init_count.quad = curr_count.quad; 00544 00545 // Make sure we didn't merge anything else. 00546 if( init_count.node != curr_count.node || init_count.edge != curr_count.edge || init_count.hex != curr_count.hex || 00547 init_count.tet != curr_count.tet ) 00548 { 00549 cout << "***ERROR: Merged other objects when merging faces.***" << endl; 00550 return MB_FAILURE; 00551 } 00552 00553 return MB_SUCCESS; 00554 } 00555 00556 ErrorCode merge_3D_elem( EntityCount& init_count, EntityCount& curr_count ) 00557 { 00558 cout << "Merging Coincident 3D Elements:" << endl; 00559 00560 // Get the list of tets from the database. 00561 Range entities; 00562 ErrorCode result = gMB->get_entities_by_type( 0, MBTET, entities ); 00563 if( result != MB_SUCCESS ) return result; 00564 00565 // find the coincident tet pairs 00566 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00567 find_coincident_elements( entities, 4, coincident ); 00568 00569 // merge the coincident tets 00570 unsigned long id1, id2; 00571 unsigned int tet_diff = coincident.size(); 00572 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00573 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00574 { 00575 id1 = gMB->id_from_handle( ( *iter ).first ); 00576 id2 = gMB->id_from_handle( ( *iter ).second ); 00577 cout << " Coincident tets: " << id1 << "-" << id2 << endl; 00578 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00579 if( result != MB_SUCCESS ) return result; 00580 } 00581 00582 // Get the list of hexs from the database. 00583 entities.clear(); 00584 result = gMB->get_entities_by_type( 0, MBHEX, entities ); 00585 if( result != MB_SUCCESS ) return result; 00586 00587 // find the coincident hex pairs 00588 coincident.clear(); 00589 find_coincident_elements( entities, 8, coincident ); 00590 00591 // merge the coincident tris 00592 unsigned int hex_diff = coincident.size(); 00593 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00594 { 00595 id1 = gMB->id_from_handle( ( *iter ).first ); 00596 id2 = gMB->id_from_handle( ( *iter ).second ); 00597 cout << " Coincident hexs: " << id1 << "-" << id2 << endl; 00598 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00599 if( result != MB_SUCCESS ) return result; 00600 } 00601 00602 // Get the reduced list of elements. 00603 curr_count.get_counts(); 00604 00605 // Make sure the coincident elements were all merged. 00606 if( init_count.tet - curr_count.tet != tet_diff ) 00607 { 00608 cout << "***ERROR: Not all coincident tets were merged.***" << endl; 00609 return MB_FAILURE; 00610 } 00611 if( init_count.hex - curr_count.hex != hex_diff ) 00612 { 00613 cout << "***ERROR: Not all coincident hexs were merged.***" << endl; 00614 return MB_FAILURE; 00615 } 00616 00617 init_count.tet = curr_count.tet; 00618 init_count.hex = curr_count.hex; 00619 00620 // Make sure we didn't merge anything else. 00621 if( init_count.node != curr_count.node || init_count.edge != curr_count.edge || 00622 init_count.quad != curr_count.quad || init_count.tri != curr_count.tri ) 00623 { 00624 cout << "***ERROR: Merged other objects when merging elements.***" << endl; 00625 return MB_FAILURE; 00626 } 00627 00628 return MB_SUCCESS; 00629 } 00630 00631 ErrorCode read_file( std::string& file_name, EntityCount& counts ) 00632 { 00633 // Make sure the database is empty. 00634 gMB->delete_mesh(); 00635 00636 // Read the model from the file. 00637 if( gMB->load_mesh( file_name.c_str(), 0 ) != MB_SUCCESS ) 00638 { 00639 cout << "***ERROR: Unable to load mesh file.***" << endl; 00640 return MB_FAILURE; 00641 } 00642 00643 // Get the number of each entity types in the mesh. 00644 if( counts.get_counts() != MB_SUCCESS ) 00645 { 00646 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00647 return MB_FAILURE; 00648 } 00649 00650 return MB_SUCCESS; 00651 } 00652 00653 ErrorCode write_file( std::string& file_name ) 00654 { 00655 // get the block tag 00656 ErrorCode result; 00657 Range block_range; 00658 Tag block_tag; 00659 00660 if( gMB->tag_get_handle( "MATERIAL_SET", block_tag ) == MB_SUCCESS ) 00661 { 00662 // get all the blocks 00663 result = gMB->get_entities_by_type_and_tag( 0, MBENTITYSET, &block_tag, 0, 1, block_range ); 00664 if( result != MB_SUCCESS ) return result; 00665 } 00666 00667 // transfer range contents into vectors 00668 std::vector< EntityHandle > output_list; 00669 00670 Range::iterator range_iter, end_iter; 00671 range_iter = block_range.begin(); 00672 end_iter = block_range.end(); 00673 00674 for( ; range_iter != end_iter; ++range_iter ) 00675 { 00676 int id; 00677 result = gMB->tag_get_handle( "MATERIAL_SET", block_tag ); 00678 if( result != MB_SUCCESS ) return result; 00679 00680 result = gMB->tag_get_data( block_tag, &*range_iter, 1, &id ); 00681 if( result != MB_SUCCESS ) return result; 00682 00683 // if(id != 2) 00684 output_list.push_back( *range_iter ); 00685 } 00686 00687 // write the file 00688 static std::string mrg_splice( ".mrg" ); 00689 file_name.insert( file_name.size() - 2, mrg_splice ); 00690 result = gMB->write_mesh( file_name.c_str(), &output_list[0], output_list.size() ); 00691 00692 return result; 00693 } 00694 00695 ErrorCode process_td_auto_merge( std::string& file_name ) 00696 { 00697 EntityCount init_count; 00698 EntityCount curr_count; 00699 EntityCount diff_count; 00700 00701 // Read in the mesh and get the number of entities of each type. 00702 if( read_file( file_name, init_count ) != MB_SUCCESS ) return MB_FAILURE; 00703 00704 // Copy the initial counts into the current count object. 00705 curr_count.copy_counts( init_count ); 00706 00707 // Print out the list of initial objects. 00708 cout << "Initial Entities:" << endl; 00709 curr_count.print(); 00710 00711 // Try auto merging from the top down. 00712 Range entities; 00713 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00714 00715 // Find how many objects of each type need to be merged. 00716 if( coincident_counts( curr_count, diff_count ) != MB_SUCCESS ) return MB_FAILURE; 00717 00718 // Find the top level object to merge. 00719 if( diff_count.hex > 0 ) 00720 { 00721 if( gMB->get_entities_by_type( 0, MBHEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00722 find_coincident_elements( entities, 8, coincident ); 00723 } 00724 else if( diff_count.quad > 0 ) 00725 { 00726 if( gMB->get_entities_by_type( 0, MBQUAD, entities ) != MB_SUCCESS ) return MB_FAILURE; 00727 find_coincident_elements( entities, 4, coincident ); 00728 } 00729 else if( diff_count.tet > 0 ) 00730 { 00731 if( gMB->get_entities_by_type( 0, MBTET, entities ) != MB_SUCCESS ) return MB_FAILURE; 00732 find_coincident_elements( entities, 4, coincident ); 00733 } 00734 else if( diff_count.tri > 0 ) 00735 { 00736 if( gMB->get_entities_by_type( 0, MBTRI, entities ) != MB_SUCCESS ) return MB_FAILURE; 00737 find_coincident_elements( entities, 3, coincident ); 00738 } 00739 else if( diff_count.edge > 0 ) 00740 { 00741 if( gMB->get_entities_by_type( 0, MBEDGE, entities ) != MB_SUCCESS ) return MB_FAILURE; 00742 find_coincident_edges( entities, coincident ); 00743 } 00744 else if( diff_count.node > 0 ) 00745 { 00746 if( gMB->get_entities_by_type( 0, MBVERTEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00747 find_coincident_nodes( entities, coincident ); 00748 } 00749 00750 cout << "Merging coincident entities(top down)..." << endl; 00751 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00752 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00753 gMB->merge_entities( ( *iter ).first, ( *iter ).second, true, true ); 00754 00755 // Get the new entity totals. 00756 if( curr_count.get_counts() != MB_SUCCESS ) 00757 { 00758 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00759 return MB_FAILURE; 00760 } 00761 00762 // Make sure we merged everything. 00763 if( init_count.node - curr_count.node != diff_count.node || init_count.edge - curr_count.edge != diff_count.edge || 00764 init_count.quad - curr_count.quad != diff_count.quad || init_count.tri - curr_count.tri != diff_count.tri || 00765 init_count.hex - curr_count.hex != diff_count.hex || init_count.tet - curr_count.tet != diff_count.tet ) 00766 { 00767 cout << "***ERROR: Not all coincident objects merged automatically.***" << endl; 00768 curr_count.print(); 00769 return MB_FAILURE; 00770 } 00771 00772 // Print out the final list of objects. 00773 cout << "Final Entities:" << endl; 00774 curr_count.print(); 00775 00776 return MB_SUCCESS; 00777 } 00778 00779 ErrorCode process_mo_auto_merge( std::string& file_name ) 00780 { 00781 EntityCount init_count; 00782 EntityCount curr_count; 00783 EntityCount diff_count; 00784 00785 // Read in the mesh and get the number of entities of each type. 00786 if( read_file( file_name, init_count ) != MB_SUCCESS ) return MB_FAILURE; 00787 00788 // Copy the initial counts into the current count object. 00789 curr_count.copy_counts( init_count ); 00790 00791 // Print out the list of initial objects. 00792 cout << "Initial Entities:" << endl; 00793 curr_count.print(); 00794 00795 // Try auto merging from the middle out. 00796 Range entities; 00797 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00798 00799 // Find how many objects of each type need to be merged. 00800 if( coincident_counts( curr_count, diff_count ) != MB_SUCCESS ) return MB_FAILURE; 00801 00802 // Start merge at the edge level if present. 00803 if( diff_count.edge > 0 ) 00804 { 00805 if( gMB->get_entities_by_type( 0, MBEDGE, entities ) != MB_SUCCESS ) return MB_FAILURE; 00806 find_coincident_edges( entities, coincident ); 00807 } 00808 else 00809 { 00810 if( gMB->get_entities_by_type( 0, MBVERTEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00811 find_coincident_nodes( entities, coincident ); 00812 } 00813 00814 cout << "Merging coincident entities(middle out)..." << endl; 00815 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00816 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00817 00818 gMB->merge_entities( ( *iter ).first, ( *iter ).second, true, true ); 00819 00820 // Get the new entity totals. 00821 if( curr_count.get_counts() != MB_SUCCESS ) 00822 { 00823 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00824 return MB_FAILURE; 00825 } 00826 00827 // Make sure we merged everything. 00828 if( init_count.node - curr_count.node != diff_count.node || init_count.edge - curr_count.edge != diff_count.edge || 00829 init_count.quad - curr_count.quad != diff_count.quad || init_count.tri - curr_count.tri != diff_count.tri || 00830 init_count.hex - curr_count.hex != diff_count.hex || init_count.tet - curr_count.tet != diff_count.tet ) 00831 { 00832 cout << "***ERROR: Not all coincident objects merged automatically.***" << endl; 00833 curr_count.print(); 00834 return MB_FAILURE; 00835 } 00836 00837 // Print out the final list of objects. 00838 cout << "Final Entities:" << endl; 00839 curr_count.print(); 00840 00841 return MB_SUCCESS; 00842 } 00843 00844 ErrorCode process_bu_auto_merge( std::string& file_name ) 00845 { 00846 EntityCount init_count; 00847 EntityCount curr_count; 00848 EntityCount diff_count; 00849 00850 // Read in the mesh and get the number of entities of each type. 00851 if( read_file( file_name, init_count ) != MB_SUCCESS ) return MB_FAILURE; 00852 00853 // Copy the initial counts into the current count object. 00854 curr_count.copy_counts( init_count ); 00855 00856 // Print out the list of initial objects. 00857 cout << "Initial Entities:" << endl; 00858 curr_count.print(); 00859 00860 // Try auto merging from the bottom up. 00861 Range entities; 00862 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00863 00864 // Find how many objects of each type need to be merged. 00865 if( coincident_counts( curr_count, diff_count ) != MB_SUCCESS ) return MB_FAILURE; 00866 00867 // Start merging from the nodes and go up. 00868 if( gMB->get_entities_by_type( 0, MBVERTEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00869 find_coincident_nodes( entities, coincident ); 00870 00871 cout << "Merging coincident entities(bottom up)..." << endl; 00872 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00873 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00874 gMB->merge_entities( ( *iter ).first, ( *iter ).second, true, true ); 00875 00876 // Get the new entity totals. 00877 if( curr_count.get_counts() != MB_SUCCESS ) 00878 { 00879 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00880 return MB_FAILURE; 00881 } 00882 00883 // Make sure we merged everything. 00884 if( init_count.node - curr_count.node != diff_count.node || init_count.edge - curr_count.edge != diff_count.edge || 00885 init_count.quad - curr_count.quad != diff_count.quad || init_count.tri - curr_count.tri != diff_count.tri || 00886 init_count.hex - curr_count.hex != diff_count.hex || init_count.tet - curr_count.tet != diff_count.tet ) 00887 { 00888 cout << "***ERROR: Not all coincident objects merged automatically.***" << endl; 00889 curr_count.print(); 00890 00891 return MB_FAILURE; 00892 } 00893 00894 // Print out the final list of objects. 00895 cout << "Final Entities:" << endl; 00896 curr_count.print(); 00897 00898 return MB_SUCCESS; 00899 } 00900 00901 ErrorCode process_merge( std::string& file_name ) 00902 { 00903 EntityCount init_count; 00904 EntityCount curr_count; 00905 00906 // Read in the mesh and get the number of entities of each type. 00907 if( read_file( file_name, init_count ) != MB_SUCCESS ) return MB_FAILURE; 00908 00909 // Copy the initial counts into the current count object. 00910 curr_count.copy_counts( init_count ); 00911 00912 // Print out the list of initial objects. 00913 cout << "Initial Entities:" << endl; 00914 curr_count.print(); 00915 00916 // Try to merge elements before nodes (should fail). 00917 if( merge_top_down( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00918 00919 // Merge the nodes. 00920 if( merge_nodes( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00921 00922 // Next, merge the edges. 00923 if( merge_edges( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00924 00925 // Now, merge the 2D elements. 00926 if( merge_2D_elem( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00927 00928 // Finally, merge the 3D elements. 00929 if( merge_3D_elem( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00930 00931 // Print out the final list of objects. 00932 if( curr_count.get_counts() != MB_SUCCESS ) 00933 { 00934 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00935 return MB_FAILURE; 00936 } 00937 cout << "Final Entities:" << endl; 00938 curr_count.print(); 00939 00940 // write the file out (modifies name) 00941 return write_file( file_name ); 00942 } 00943 00944 int main() 00945 { 00946 ErrorCode result; 00947 std::string test_files[] = { 00948 std::string( "test/2barcase1.g" ), std::string( "test/2barcase2.g" ), std::string( "test/2hexcase1.g" ), 00949 std::string( "test/2hexcase2.g" ), std::string( "test/2hexcase3.g" ), std::string( "test/2hexcase4.g" ), 00950 std::string( "test/2hexcase5.g" ), std::string( "test/2quadcase1.g" ), std::string( "test/2quadcase2.g" ), 00951 std::string( "test/2quadcase3.g" ), std::string( "test/2quadcase4.g" ), std::string( "test/2tetcase1.g" ), 00952 std::string( "test/2tetcase2.g" ), std::string( "test/2tetcase3.g" ), std::string( "test/2tetcase4.g" ), 00953 std::string( "test/2tricase1.g" ), std::string( "test/2tricase2.g" ), std::string( "test/2tricase3.g" ) 00954 }; 00955 00956 // Create the MB database instance. 00957 gMB = new Core(); 00958 00959 // Loop through the list of test files. 00960 unsigned int i; 00961 cout << "---Starting Top Down Auto Merge Tests---" << endl << endl; 00962 for( i = 0; i < ( sizeof( test_files ) / sizeof( std::string ) ); i++ ) 00963 { 00964 cout << "---Testing:\"" << test_files[i] << "\"---" << endl; 00965 result = process_td_auto_merge( test_files[i] ); 00966 if( result == MB_SUCCESS ) 00967 cout << "---Success---"; 00968 else 00969 cout << "---Failure---"; 00970 cout << endl << endl; 00971 } 00972 00973 cout << "---Starting Bottom Up Auto Merge Tests---" << endl << endl; 00974 for( i = 0; i < ( sizeof( test_files ) / sizeof( std::string ) ); i++ ) 00975 { 00976 cout << "---Testing:\"" << test_files[i] << "\"---" << endl; 00977 result = process_bu_auto_merge( test_files[i] ); 00978 if( result == MB_SUCCESS ) 00979 00980 cout << "---Success---"; 00981 else 00982 cout << "---Failure---"; 00983 cout << endl << endl; 00984 } 00985 00986 cout << "---Starting Middle Out Auto Merge Tests---" << endl << endl; 00987 for( i = 0; i < ( sizeof( test_files ) / sizeof( std::string ) ); i++ ) 00988 { 00989 cout << "---Testing:\"" << test_files[i] << "\"---" << endl; 00990 result = process_mo_auto_merge( test_files[i] ); 00991 if( result == MB_SUCCESS ) 00992 cout << "---Success---"; 00993 else 00994 cout << "---Failure---"; 00995 00996 cout << endl << endl; 00997 } 00998 00999 cout << "---Starting Merge Tests---" << endl << endl; 01000 for( i = 0; i < ( sizeof( test_files ) / sizeof( std::string ) ); i++ ) 01001 { 01002 cout << "---Testing:\"" << test_files[i] << "\"---" << endl; 01003 result = process_merge( test_files[i] ); 01004 if( result == MB_SUCCESS ) 01005 cout << "---Success---"; 01006 else 01007 cout << "---Failure---"; 01008 cout << endl << endl; 01009 } 01010 01011 // Destroy the MB database instance. 01012 delete gMB; 01013 gMB = NULL; 01014 }