MOAB: Mesh Oriented datABase
(version 5.4.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, 00215 int num_nodes, 00216 std::vector< std::pair< EntityHandle, EntityHandle > >& coin ) 00217 { 00218 double coords1[8][3], coords2[8][3]; 00219 Range::iterator iter, jter; 00220 std::vector< EntityHandle > conn( 8 ); 00221 std::pair< EntityHandle, EntityHandle > coincident_pair; 00222 int i = 0, j = 0, ii = 0; 00223 00224 for( iter = entities.begin(); iter != entities.end(); ++iter ) 00225 { 00226 // Get the coordinates for the element corners. 00227 if( gMB->get_connectivity( &*iter, 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 00228 for( ii = 0; ii < num_nodes; ii++ ) 00229 { 00230 if( gMB->get_coords( &conn[ii], 1, coords1[ii] ) != MB_SUCCESS ) return MB_FAILURE; 00231 } 00232 00233 for( jter = iter; jter != entities.end(); ++jter ) 00234 { 00235 if( *iter != *jter ) 00236 { 00237 // Elements should be the same sense to merge. 00238 if( gMB->get_connectivity( &*jter, 1, conn ) != MB_SUCCESS ) return MB_FAILURE; 00239 00240 if( gMB->get_coords( &conn[0], 1, coords2[0] ) != MB_SUCCESS ) return MB_FAILURE; 00241 00242 // Find if first node is coincident before testing the rest. 00243 for( i = 0; i < num_nodes; i++ ) 00244 { 00245 if( points_are_coincident( coords1[i], coords2[0] ) ) break; 00246 } 00247 00248 if( i < num_nodes ) 00249 { 00250 for( ii = 1; ii < num_nodes; ii++ ) 00251 { 00252 if( gMB->get_coords( &conn[ii], 1, coords2[ii] ) != MB_SUCCESS ) return MB_FAILURE; 00253 } 00254 00255 for( j = 1; j < num_nodes; j++ ) 00256 { 00257 if( !points_are_coincident( coords1[j], coords2[( j + i ) % num_nodes] ) ) break; 00258 } 00259 00260 if( j == num_nodes ) 00261 00262 { 00263 coincident_pair.first = *iter; 00264 coincident_pair.second = *jter; 00265 coin.push_back( coincident_pair ); 00266 } 00267 } 00268 } 00269 } 00270 } 00271 00272 return MB_SUCCESS; 00273 } 00274 00275 ErrorCode coincident_counts( EntityCount& curr_count, EntityCount& diff_count ) 00276 { 00277 Range entities; 00278 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00279 00280 if( curr_count.node > 0 ) 00281 { 00282 if( gMB->get_entities_by_type( 0, MBVERTEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00283 find_coincident_nodes( entities, coincident ); 00284 diff_count.node = coincident.size(); 00285 entities.clear(); 00286 coincident.clear(); 00287 } 00288 if( curr_count.edge > 0 ) 00289 { 00290 if( gMB->get_entities_by_type( 0, MBEDGE, entities ) != MB_SUCCESS ) return MB_FAILURE; 00291 find_coincident_edges( entities, coincident ); 00292 diff_count.edge = coincident.size(); 00293 entities.clear(); 00294 coincident.clear(); 00295 } 00296 if( curr_count.quad > 0 ) 00297 { 00298 if( gMB->get_entities_by_type( 0, MBQUAD, entities ) != MB_SUCCESS ) return MB_FAILURE; 00299 find_coincident_elements( entities, 4, coincident ); 00300 diff_count.quad = coincident.size(); 00301 entities.clear(); 00302 coincident.clear(); 00303 } 00304 if( curr_count.tri > 0 ) 00305 { 00306 if( gMB->get_entities_by_type( 0, MBTRI, entities ) != MB_SUCCESS ) return MB_FAILURE; 00307 find_coincident_elements( entities, 3, coincident ); 00308 diff_count.tri = coincident.size(); 00309 entities.clear(); 00310 coincident.clear(); 00311 } 00312 if( curr_count.tet > 0 ) 00313 { 00314 if( gMB->get_entities_by_type( 0, MBTET, entities ) != MB_SUCCESS ) return MB_FAILURE; 00315 find_coincident_elements( entities, 4, coincident ); 00316 diff_count.tet = coincident.size(); 00317 entities.clear(); 00318 coincident.clear(); 00319 } 00320 if( curr_count.hex > 0 ) 00321 { 00322 if( gMB->get_entities_by_type( 0, MBHEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00323 find_coincident_elements( entities, 8, coincident ); 00324 diff_count.hex = coincident.size(); 00325 entities.clear(); 00326 coincident.clear(); 00327 } 00328 00329 return MB_SUCCESS; 00330 } 00331 00332 ErrorCode merge_top_down( EntityCount& init_count, EntityCount& curr_count ) 00333 { 00334 Range entities; 00335 EntityCount diff_count; 00336 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00337 00338 // Find how many objects of each type need to be merged. 00339 if( coincident_counts( curr_count, diff_count ) != MB_SUCCESS ) return MB_FAILURE; 00340 00341 // Find the top level object to merge. 00342 if( diff_count.hex > 0 ) 00343 { 00344 if( gMB->get_entities_by_type( 0, MBHEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00345 find_coincident_elements( entities, 8, coincident ); 00346 } 00347 else if( diff_count.quad > 0 ) 00348 { 00349 if( gMB->get_entities_by_type( 0, MBQUAD, entities ) != MB_SUCCESS ) return MB_FAILURE; 00350 find_coincident_elements( entities, 4, coincident ); 00351 } 00352 else if( diff_count.tet > 0 ) 00353 { 00354 if( gMB->get_entities_by_type( 0, MBTET, entities ) != MB_SUCCESS ) return MB_FAILURE; 00355 find_coincident_elements( entities, 4, coincident ); 00356 } 00357 else if( diff_count.tri > 0 ) 00358 00359 { 00360 if( gMB->get_entities_by_type( 0, MBTRI, entities ) != MB_SUCCESS ) return MB_FAILURE; 00361 find_coincident_elements( entities, 3, coincident ); 00362 } 00363 else if( diff_count.edge > 0 ) 00364 { 00365 if( gMB->get_entities_by_type( 0, MBEDGE, entities ) != MB_SUCCESS ) return MB_FAILURE; 00366 find_coincident_edges( entities, coincident ); 00367 } 00368 00369 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00370 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00371 gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00372 00373 // Get the new entity totals. 00374 curr_count.get_counts(); 00375 00376 // Make sure we didn't merge anything. 00377 if( init_count.node != curr_count.node || init_count.edge != curr_count.edge || 00378 init_count.quad != curr_count.quad || init_count.tri != curr_count.tri || init_count.hex != curr_count.hex || 00379 init_count.tet != curr_count.tet ) 00380 { 00381 cout << "***ERROR: Merged top down when not using auto merge.***" << endl; 00382 return MB_FAILURE; 00383 } 00384 00385 return MB_SUCCESS; 00386 } 00387 00388 ErrorCode merge_nodes( EntityCount& init_count, EntityCount& curr_count ) 00389 { 00390 cout << "Merging Coincident Nodes:" << endl; 00391 00392 // Get the list of vertices from the database. 00393 Range vertices; 00394 ErrorCode result = gMB->get_entities_by_type( 0, MBVERTEX, vertices ); 00395 if( result != MB_SUCCESS ) return result; 00396 00397 // find the coincident node pairs 00398 std::vector< std::pair< EntityHandle, EntityHandle > > coincident_nodes; 00399 find_coincident_nodes( vertices, coincident_nodes ); 00400 00401 // merge the coincident nodes 00402 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00403 for( iter = coincident_nodes.begin(); iter != coincident_nodes.end(); ++iter ) 00404 { 00405 cout << " Coincident nodes: " << ( *iter ).first << "-" << ( *iter ).second << endl; 00406 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00407 if( result != MB_SUCCESS ) return result; 00408 } 00409 00410 // Get the reduced list of vertices. 00411 curr_count.get_counts(); 00412 00413 // Make sure the coincident nodes were all merged. 00414 if( init_count.node - curr_count.node != coincident_nodes.size() ) 00415 { 00416 cout << "***ERROR: Not all coincident nodes were merged.***" << endl; 00417 return MB_FAILURE; 00418 } 00419 00420 init_count.node = curr_count.node; 00421 00422 // Make sure we didn't merge anything else. 00423 if( init_count.edge != curr_count.edge || init_count.quad != curr_count.quad || init_count.tri != curr_count.tri || 00424 init_count.hex != curr_count.hex || init_count.tet != curr_count.tet ) 00425 { 00426 cout << "***ERROR: Merged other objects when merging nodes.***" << endl; 00427 return MB_FAILURE; 00428 } 00429 00430 return MB_SUCCESS; 00431 } 00432 00433 ErrorCode merge_edges( EntityCount& init_count, EntityCount& curr_count ) 00434 { 00435 cout << "Merging Coincident Edges:" << endl; 00436 00437 // Get the list of entities from the database. 00438 Range entities; 00439 ErrorCode result = gMB->get_entities_by_type( 0, MBEDGE, entities ); 00440 if( result != MB_SUCCESS ) return result; 00441 00442 // find the coincident edge pairs 00443 std::vector< std::pair< EntityHandle, EntityHandle > > coincident_edges; 00444 find_coincident_edges( entities, coincident_edges ); 00445 00446 // merge the coincident edges 00447 unsigned long id1, id2; 00448 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00449 for( iter = coincident_edges.begin(); iter != coincident_edges.end(); ++iter ) 00450 { 00451 id1 = gMB->id_from_handle( ( *iter ).first ); 00452 id2 = gMB->id_from_handle( ( *iter ).second ); 00453 cout << " Coincident edges: " << id1 << "-" << id2 << endl; 00454 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00455 if( result != MB_SUCCESS ) return result; 00456 } 00457 00458 // Get the reduced list of edges. 00459 curr_count.get_counts(); 00460 00461 // Make sure the coincident edges were all merged. 00462 if( init_count.edge - curr_count.edge != coincident_edges.size() ) 00463 { 00464 cout << "***ERROR: Not all coincident edges were merged.***" << endl; 00465 return MB_FAILURE; 00466 } 00467 00468 init_count.edge = curr_count.edge; 00469 00470 // Make sure we didn't merge anything else. 00471 if( init_count.node != curr_count.node || init_count.quad != curr_count.quad || init_count.tri != curr_count.tri || 00472 init_count.hex != curr_count.hex || init_count.tet != curr_count.tet ) 00473 { 00474 cout << "***ERROR: Merged other objects when merging edges.***" << endl; 00475 return MB_FAILURE; 00476 } 00477 00478 return MB_SUCCESS; 00479 } 00480 00481 ErrorCode merge_2D_elem( EntityCount& init_count, EntityCount& curr_count ) 00482 { 00483 cout << "Merging Coincident 2D Elements:" << endl; 00484 00485 // Get the list of tris from the database. 00486 Range entities; 00487 ErrorCode result = gMB->get_entities_by_type( 0, MBTRI, entities ); 00488 if( result != MB_SUCCESS ) return result; 00489 00490 // find the coincident tri pairs 00491 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00492 find_coincident_elements( entities, 3, coincident ); 00493 00494 // merge the coincident tris 00495 unsigned long id1, id2; 00496 unsigned int tri_diff = coincident.size(); 00497 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00498 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00499 { 00500 id1 = gMB->id_from_handle( ( *iter ).first ); 00501 id2 = gMB->id_from_handle( ( *iter ).second ); 00502 cout << " Coincident tris: " << id1 << "-" << id2 << endl; 00503 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00504 00505 if( result != MB_SUCCESS ) return result; 00506 } 00507 00508 // Get the list of quads from the database. 00509 entities.clear(); 00510 result = gMB->get_entities_by_type( 0, MBQUAD, entities ); 00511 if( result != MB_SUCCESS ) return result; 00512 00513 // find the coincident tri pairs 00514 coincident.clear(); 00515 find_coincident_elements( entities, 4, coincident ); 00516 00517 // merge the coincident tris 00518 unsigned int quad_diff = coincident.size(); 00519 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00520 { 00521 id1 = gMB->id_from_handle( ( *iter ).first ); 00522 id2 = gMB->id_from_handle( ( *iter ).second ); 00523 cout << " Coincident quads: " << id1 << "-" << id2 << endl; 00524 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00525 if( result != MB_SUCCESS ) return result; 00526 } 00527 00528 // Get the reduced list of faces. 00529 curr_count.get_counts(); 00530 00531 // Make sure the coincident faces were all merged. 00532 if( init_count.tri - curr_count.tri != tri_diff ) 00533 { 00534 cout << "***ERROR: Not all coincident tris were merged.***" << endl; 00535 return MB_FAILURE; 00536 } 00537 if( init_count.quad - curr_count.quad != quad_diff ) 00538 { 00539 cout << "***ERROR: Not all coincident quads were merged.***" << endl; 00540 return MB_FAILURE; 00541 } 00542 00543 init_count.tri = curr_count.tri; 00544 init_count.quad = curr_count.quad; 00545 00546 // Make sure we didn't merge anything else. 00547 if( init_count.node != curr_count.node || init_count.edge != curr_count.edge || init_count.hex != curr_count.hex || 00548 init_count.tet != curr_count.tet ) 00549 { 00550 cout << "***ERROR: Merged other objects when merging faces.***" << endl; 00551 return MB_FAILURE; 00552 } 00553 00554 return MB_SUCCESS; 00555 } 00556 00557 ErrorCode merge_3D_elem( EntityCount& init_count, EntityCount& curr_count ) 00558 { 00559 cout << "Merging Coincident 3D Elements:" << endl; 00560 00561 // Get the list of tets from the database. 00562 Range entities; 00563 ErrorCode result = gMB->get_entities_by_type( 0, MBTET, entities ); 00564 if( result != MB_SUCCESS ) return result; 00565 00566 // find the coincident tet pairs 00567 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00568 find_coincident_elements( entities, 4, coincident ); 00569 00570 // merge the coincident tets 00571 unsigned long id1, id2; 00572 unsigned int tet_diff = coincident.size(); 00573 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00574 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00575 { 00576 id1 = gMB->id_from_handle( ( *iter ).first ); 00577 id2 = gMB->id_from_handle( ( *iter ).second ); 00578 cout << " Coincident tets: " << id1 << "-" << id2 << endl; 00579 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00580 if( result != MB_SUCCESS ) return result; 00581 } 00582 00583 // Get the list of hexs from the database. 00584 entities.clear(); 00585 result = gMB->get_entities_by_type( 0, MBHEX, entities ); 00586 if( result != MB_SUCCESS ) return result; 00587 00588 // find the coincident hex pairs 00589 coincident.clear(); 00590 find_coincident_elements( entities, 8, coincident ); 00591 00592 // merge the coincident tris 00593 unsigned int hex_diff = coincident.size(); 00594 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00595 { 00596 id1 = gMB->id_from_handle( ( *iter ).first ); 00597 id2 = gMB->id_from_handle( ( *iter ).second ); 00598 cout << " Coincident hexs: " << id1 << "-" << id2 << endl; 00599 result = gMB->merge_entities( ( *iter ).first, ( *iter ).second, false, true ); 00600 if( result != MB_SUCCESS ) return result; 00601 } 00602 00603 // Get the reduced list of elements. 00604 curr_count.get_counts(); 00605 00606 // Make sure the coincident elements were all merged. 00607 if( init_count.tet - curr_count.tet != tet_diff ) 00608 { 00609 cout << "***ERROR: Not all coincident tets were merged.***" << endl; 00610 return MB_FAILURE; 00611 } 00612 if( init_count.hex - curr_count.hex != hex_diff ) 00613 { 00614 cout << "***ERROR: Not all coincident hexs were merged.***" << endl; 00615 return MB_FAILURE; 00616 } 00617 00618 init_count.tet = curr_count.tet; 00619 init_count.hex = curr_count.hex; 00620 00621 // Make sure we didn't merge anything else. 00622 if( init_count.node != curr_count.node || init_count.edge != curr_count.edge || 00623 init_count.quad != curr_count.quad || init_count.tri != curr_count.tri ) 00624 { 00625 cout << "***ERROR: Merged other objects when merging elements.***" << endl; 00626 return MB_FAILURE; 00627 } 00628 00629 return MB_SUCCESS; 00630 } 00631 00632 ErrorCode read_file( std::string& file_name, EntityCount& counts ) 00633 { 00634 // Make sure the database is empty. 00635 gMB->delete_mesh(); 00636 00637 // Read the model from the file. 00638 if( gMB->load_mesh( file_name.c_str(), 0 ) != MB_SUCCESS ) 00639 { 00640 cout << "***ERROR: Unable to load mesh file.***" << endl; 00641 return MB_FAILURE; 00642 } 00643 00644 // Get the number of each entity types in the mesh. 00645 if( counts.get_counts() != MB_SUCCESS ) 00646 { 00647 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00648 return MB_FAILURE; 00649 } 00650 00651 return MB_SUCCESS; 00652 } 00653 00654 ErrorCode write_file( std::string& file_name ) 00655 { 00656 // get the block tag 00657 ErrorCode result; 00658 Range block_range; 00659 Tag block_tag; 00660 00661 if( gMB->tag_get_handle( "MATERIAL_SET", block_tag ) == MB_SUCCESS ) 00662 { 00663 // get all the blocks 00664 result = gMB->get_entities_by_type_and_tag( 0, MBENTITYSET, &block_tag, 0, 1, block_range ); 00665 if( result != MB_SUCCESS ) return result; 00666 } 00667 00668 // transfer range contents into vectors 00669 std::vector< EntityHandle > output_list; 00670 00671 Range::iterator range_iter, end_iter; 00672 range_iter = block_range.begin(); 00673 end_iter = block_range.end(); 00674 00675 for( ; range_iter != end_iter; ++range_iter ) 00676 { 00677 int id; 00678 result = gMB->tag_get_handle( "MATERIAL_SET", block_tag ); 00679 if( result != MB_SUCCESS ) return result; 00680 00681 result = gMB->tag_get_data( block_tag, &*range_iter, 1, &id ); 00682 if( result != MB_SUCCESS ) return result; 00683 00684 // if(id != 2) 00685 output_list.push_back( *range_iter ); 00686 } 00687 00688 // write the file 00689 static std::string mrg_splice( ".mrg" ); 00690 file_name.insert( file_name.size() - 2, mrg_splice ); 00691 result = gMB->write_mesh( file_name.c_str(), &output_list[0], output_list.size() ); 00692 00693 return result; 00694 } 00695 00696 ErrorCode process_td_auto_merge( std::string& file_name ) 00697 { 00698 EntityCount init_count; 00699 EntityCount curr_count; 00700 EntityCount diff_count; 00701 00702 // Read in the mesh and get the number of entities of each type. 00703 if( read_file( file_name, init_count ) != MB_SUCCESS ) return MB_FAILURE; 00704 00705 // Copy the initial counts into the current count object. 00706 curr_count.copy_counts( init_count ); 00707 00708 // Print out the list of initial objects. 00709 cout << "Initial Entities:" << endl; 00710 curr_count.print(); 00711 00712 // Try auto merging from the top down. 00713 Range entities; 00714 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00715 00716 // Find how many objects of each type need to be merged. 00717 if( coincident_counts( curr_count, diff_count ) != MB_SUCCESS ) return MB_FAILURE; 00718 00719 // Find the top level object to merge. 00720 if( diff_count.hex > 0 ) 00721 { 00722 if( gMB->get_entities_by_type( 0, MBHEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00723 find_coincident_elements( entities, 8, coincident ); 00724 } 00725 else if( diff_count.quad > 0 ) 00726 { 00727 if( gMB->get_entities_by_type( 0, MBQUAD, entities ) != MB_SUCCESS ) return MB_FAILURE; 00728 find_coincident_elements( entities, 4, coincident ); 00729 } 00730 else if( diff_count.tet > 0 ) 00731 { 00732 if( gMB->get_entities_by_type( 0, MBTET, entities ) != MB_SUCCESS ) return MB_FAILURE; 00733 find_coincident_elements( entities, 4, coincident ); 00734 } 00735 else if( diff_count.tri > 0 ) 00736 { 00737 if( gMB->get_entities_by_type( 0, MBTRI, entities ) != MB_SUCCESS ) return MB_FAILURE; 00738 find_coincident_elements( entities, 3, coincident ); 00739 } 00740 else if( diff_count.edge > 0 ) 00741 { 00742 if( gMB->get_entities_by_type( 0, MBEDGE, entities ) != MB_SUCCESS ) return MB_FAILURE; 00743 find_coincident_edges( entities, coincident ); 00744 } 00745 else if( diff_count.node > 0 ) 00746 { 00747 if( gMB->get_entities_by_type( 0, MBVERTEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00748 find_coincident_nodes( entities, coincident ); 00749 } 00750 00751 cout << "Merging coincident entities(top down)..." << endl; 00752 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00753 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00754 gMB->merge_entities( ( *iter ).first, ( *iter ).second, true, true ); 00755 00756 // Get the new entity totals. 00757 if( curr_count.get_counts() != MB_SUCCESS ) 00758 { 00759 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00760 return MB_FAILURE; 00761 } 00762 00763 // Make sure we merged everything. 00764 if( init_count.node - curr_count.node != diff_count.node || init_count.edge - curr_count.edge != diff_count.edge || 00765 init_count.quad - curr_count.quad != diff_count.quad || init_count.tri - curr_count.tri != diff_count.tri || 00766 init_count.hex - curr_count.hex != diff_count.hex || init_count.tet - curr_count.tet != diff_count.tet ) 00767 { 00768 cout << "***ERROR: Not all coincident objects merged automatically.***" << endl; 00769 curr_count.print(); 00770 return MB_FAILURE; 00771 } 00772 00773 // Print out the final list of objects. 00774 cout << "Final Entities:" << endl; 00775 curr_count.print(); 00776 00777 return MB_SUCCESS; 00778 } 00779 00780 ErrorCode process_mo_auto_merge( std::string& file_name ) 00781 { 00782 EntityCount init_count; 00783 EntityCount curr_count; 00784 EntityCount diff_count; 00785 00786 // Read in the mesh and get the number of entities of each type. 00787 if( read_file( file_name, init_count ) != MB_SUCCESS ) return MB_FAILURE; 00788 00789 // Copy the initial counts into the current count object. 00790 curr_count.copy_counts( init_count ); 00791 00792 // Print out the list of initial objects. 00793 cout << "Initial Entities:" << endl; 00794 curr_count.print(); 00795 00796 // Try auto merging from the middle out. 00797 Range entities; 00798 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00799 00800 // Find how many objects of each type need to be merged. 00801 if( coincident_counts( curr_count, diff_count ) != MB_SUCCESS ) return MB_FAILURE; 00802 00803 // Start merge at the edge level if present. 00804 if( diff_count.edge > 0 ) 00805 { 00806 if( gMB->get_entities_by_type( 0, MBEDGE, entities ) != MB_SUCCESS ) return MB_FAILURE; 00807 find_coincident_edges( entities, coincident ); 00808 } 00809 else 00810 { 00811 if( gMB->get_entities_by_type( 0, MBVERTEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00812 find_coincident_nodes( entities, coincident ); 00813 } 00814 00815 cout << "Merging coincident entities(middle out)..." << endl; 00816 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00817 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00818 00819 gMB->merge_entities( ( *iter ).first, ( *iter ).second, true, true ); 00820 00821 // Get the new entity totals. 00822 if( curr_count.get_counts() != MB_SUCCESS ) 00823 { 00824 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00825 return MB_FAILURE; 00826 } 00827 00828 // Make sure we merged everything. 00829 if( init_count.node - curr_count.node != diff_count.node || init_count.edge - curr_count.edge != diff_count.edge || 00830 init_count.quad - curr_count.quad != diff_count.quad || init_count.tri - curr_count.tri != diff_count.tri || 00831 init_count.hex - curr_count.hex != diff_count.hex || init_count.tet - curr_count.tet != diff_count.tet ) 00832 { 00833 cout << "***ERROR: Not all coincident objects merged automatically.***" << endl; 00834 curr_count.print(); 00835 return MB_FAILURE; 00836 } 00837 00838 // Print out the final list of objects. 00839 cout << "Final Entities:" << endl; 00840 curr_count.print(); 00841 00842 return MB_SUCCESS; 00843 } 00844 00845 ErrorCode process_bu_auto_merge( std::string& file_name ) 00846 { 00847 EntityCount init_count; 00848 EntityCount curr_count; 00849 EntityCount diff_count; 00850 00851 // Read in the mesh and get the number of entities of each type. 00852 if( read_file( file_name, init_count ) != MB_SUCCESS ) return MB_FAILURE; 00853 00854 // Copy the initial counts into the current count object. 00855 curr_count.copy_counts( init_count ); 00856 00857 // Print out the list of initial objects. 00858 cout << "Initial Entities:" << endl; 00859 curr_count.print(); 00860 00861 // Try auto merging from the bottom up. 00862 Range entities; 00863 std::vector< std::pair< EntityHandle, EntityHandle > > coincident; 00864 00865 // Find how many objects of each type need to be merged. 00866 if( coincident_counts( curr_count, diff_count ) != MB_SUCCESS ) return MB_FAILURE; 00867 00868 // Start merging from the nodes and go up. 00869 if( gMB->get_entities_by_type( 0, MBVERTEX, entities ) != MB_SUCCESS ) return MB_FAILURE; 00870 find_coincident_nodes( entities, coincident ); 00871 00872 cout << "Merging coincident entities(bottom up)..." << endl; 00873 std::vector< std::pair< EntityHandle, EntityHandle > >::iterator iter; 00874 for( iter = coincident.begin(); iter != coincident.end(); ++iter ) 00875 gMB->merge_entities( ( *iter ).first, ( *iter ).second, true, true ); 00876 00877 // Get the new entity totals. 00878 if( curr_count.get_counts() != MB_SUCCESS ) 00879 { 00880 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00881 return MB_FAILURE; 00882 } 00883 00884 // Make sure we merged everything. 00885 if( init_count.node - curr_count.node != diff_count.node || init_count.edge - curr_count.edge != diff_count.edge || 00886 init_count.quad - curr_count.quad != diff_count.quad || init_count.tri - curr_count.tri != diff_count.tri || 00887 init_count.hex - curr_count.hex != diff_count.hex || init_count.tet - curr_count.tet != diff_count.tet ) 00888 { 00889 cout << "***ERROR: Not all coincident objects merged automatically.***" << endl; 00890 curr_count.print(); 00891 00892 return MB_FAILURE; 00893 } 00894 00895 // Print out the final list of objects. 00896 cout << "Final Entities:" << endl; 00897 curr_count.print(); 00898 00899 return MB_SUCCESS; 00900 } 00901 00902 ErrorCode process_merge( std::string& file_name ) 00903 { 00904 EntityCount init_count; 00905 EntityCount curr_count; 00906 00907 // Read in the mesh and get the number of entities of each type. 00908 if( read_file( file_name, init_count ) != MB_SUCCESS ) return MB_FAILURE; 00909 00910 // Copy the initial counts into the current count object. 00911 curr_count.copy_counts( init_count ); 00912 00913 // Print out the list of initial objects. 00914 cout << "Initial Entities:" << endl; 00915 curr_count.print(); 00916 00917 // Try to merge elements before nodes (should fail). 00918 if( merge_top_down( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00919 00920 // Merge the nodes. 00921 if( merge_nodes( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00922 00923 // Next, merge the edges. 00924 if( merge_edges( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00925 00926 // Now, merge the 2D elements. 00927 if( merge_2D_elem( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00928 00929 // Finally, merge the 3D elements. 00930 if( merge_3D_elem( init_count, curr_count ) != MB_SUCCESS ) return MB_FAILURE; 00931 00932 // Print out the final list of objects. 00933 if( curr_count.get_counts() != MB_SUCCESS ) 00934 { 00935 cout << "***ERROR: Unable to get entity list counts.***" << endl; 00936 return MB_FAILURE; 00937 } 00938 cout << "Final Entities:" << endl; 00939 curr_count.print(); 00940 00941 // write the file out (modifies name) 00942 return write_file( file_name ); 00943 } 00944 00945 int main() 00946 { 00947 ErrorCode result; 00948 std::string test_files[] = { 00949 std::string( "test/2barcase1.g" ), std::string( "test/2barcase2.g" ), std::string( "test/2hexcase1.g" ), 00950 std::string( "test/2hexcase2.g" ), std::string( "test/2hexcase3.g" ), std::string( "test/2hexcase4.g" ), 00951 std::string( "test/2hexcase5.g" ), std::string( "test/2quadcase1.g" ), std::string( "test/2quadcase2.g" ), 00952 std::string( "test/2quadcase3.g" ), std::string( "test/2quadcase4.g" ), std::string( "test/2tetcase1.g" ), 00953 std::string( "test/2tetcase2.g" ), std::string( "test/2tetcase3.g" ), std::string( "test/2tetcase4.g" ), 00954 std::string( "test/2tricase1.g" ), std::string( "test/2tricase2.g" ), std::string( "test/2tricase3.g" ) }; 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 }