MOAB: Mesh Oriented datABase  (version 5.2.1)
merge_test.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines