MOAB: Mesh Oriented datABase  (version 5.2.1)
MeshImplData.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2004 Lawrence Livermore National Laboratory.  Under
00005     the terms of Contract B545069 with the University of Wisconsin --
00006     Madison, Lawrence Livermore National Laboratory retains certain
00007     rights in this software.
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Lesser General Public
00011     License as published by the Free Software Foundation; either
00012     version 2.1 of the License, or (at your option) any later version.
00013 
00014     This library is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017     Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     (lgpl.txt) along with this library; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023     kraftche@cae.wisc.edu
00024 
00025   ***************************************************************** */
00026 
00027 #include "MeshImplData.hpp"
00028 #include "TopologyInfo.hpp"
00029 #include "MsqError.hpp"
00030 
00031 // NOTE: If this is defined, the normal vertex query functions
00032 //       will not return mid-nodes.
00033 #undef SEPARATE_MID_NODES
00034 
00035 namespace MBMesquite
00036 {
00037 
00038 const std::vector< size_t > dummy_list;
00039 const Vector3D dummy_vtx;
00040 
00041 size_t MeshImplData::num_vertices() const
00042 {
00043     size_t count = 0;
00044     for( std::vector< Vertex >::const_iterator iter = vertexList.begin(); iter != vertexList.end(); ++iter )
00045 #ifdef SEPARATE_MID_NODES
00046         if( iter->valid && iter->midcount < iter->adjacencies.size() )
00047 #else
00048         if( iter->valid )
00049 #endif
00050             ++count;
00051     return count;
00052 }
00053 
00054 size_t MeshImplData::num_elements() const
00055 {
00056     return elementList.size() - deletedElementList.size();
00057 }
00058 
00059 size_t MeshImplData::num_vertex_uses() const
00060 {
00061     size_t result = 0;
00062     for( std::vector< Element >::const_iterator iter = elementList.begin(); iter != elementList.end(); ++iter )
00063     {
00064 #ifdef SEPARATE_MID_NODES
00065         unsigned from_topo = TopologyInfo::corners( iter->topology );
00066         result += from_topo ? from_topo : iter->connectivity.size();
00067 #else
00068         result += iter->connectivity.size();
00069 #endif
00070     }
00071     return result;
00072 }
00073 
00074 const Vector3D& MeshImplData::get_vertex_coords( size_t index, MsqError& err ) const
00075 {
00076     if( !is_vertex_valid( index ) )
00077     {
00078         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00079         return dummy_vtx;
00080     }
00081 
00082     return vertexList[index].coords;
00083 }
00084 
00085 bool MeshImplData::vertex_is_fixed( size_t index, MsqError& err ) const
00086 {
00087     if( !is_vertex_valid( index ) )
00088     {
00089         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00090         return false;
00091     }
00092 
00093     return vertexList[index].fixed;
00094 }
00095 
00096 bool MeshImplData::vertex_is_slaved( size_t index, MsqError& err ) const
00097 {
00098     if( !is_vertex_valid( index ) )
00099     {
00100         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00101         return false;
00102     }
00103     if( !have_slaved_flags() )
00104     {
00105         MSQ_SETERR( err )( "Slave flags not set", MsqError::INVALID_STATE );
00106         return false;
00107     }
00108 
00109     return vertexList[index].slaved;
00110 }
00111 
00112 void MeshImplData::fix_vertex( size_t index, bool flag, MsqError& err )
00113 {
00114     if( !is_vertex_valid( index ) )
00115     {
00116         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00117         return;
00118     }
00119 
00120     vertexList[index].fixed = flag;
00121 }
00122 
00123 void MeshImplData::slave_vertex( size_t index, bool flag, MsqError& err )
00124 {
00125     if( !is_vertex_valid( index ) )
00126     {
00127         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00128         return;
00129     }
00130 
00131     vertexList[index].slaved = flag;
00132     haveSlavedFlags          = true;
00133 }
00134 
00135 unsigned char MeshImplData::get_vertex_byte( size_t index, MsqError& err ) const
00136 {
00137     if( !is_vertex_valid( index ) )
00138     {
00139         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00140         return 0;
00141     }
00142 
00143     return vertexList[index].byte;
00144 }
00145 
00146 void MeshImplData::set_vertex_byte( size_t index, unsigned char value, MsqError& err )
00147 {
00148     if( !is_vertex_valid( index ) )
00149     {
00150         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00151         return;
00152     }
00153 
00154     vertexList[index].byte = value;
00155 }
00156 
00157 EntityTopology MeshImplData::element_topology( size_t index, MsqError& err ) const
00158 {
00159     if( !is_element_valid( index ) )
00160     {
00161         MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
00162         return MIXED;
00163     }
00164 
00165     return elementList[index].topology;
00166 }
00167 
00168 void MeshImplData::element_topology( size_t index, EntityTopology type, MsqError& err )
00169 {
00170     if( !is_element_valid( index ) )
00171     {
00172         MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
00173         return;
00174     }
00175 
00176     unsigned i, numvert;
00177 
00178     numvert = TopologyInfo::corners( elementList[index].topology );
00179     if( numvert )
00180         for( i = numvert; i < elementList[index].connectivity.size(); ++i )
00181             --vertexList[elementList[index].connectivity[i]].midcount;
00182 
00183     elementList[index].topology = type;
00184 
00185     numvert = TopologyInfo::corners( elementList[index].topology );
00186     if( numvert )
00187         for( i = numvert; i < elementList[index].connectivity.size(); ++i )
00188             ++vertexList[elementList[index].connectivity[i]].midcount;
00189 }
00190 
00191 const std::vector< size_t >& MeshImplData::element_connectivity( size_t index, MsqError& err ) const
00192 {
00193     if( !is_element_valid( index ) )
00194     {
00195         MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
00196         return dummy_list;
00197     }
00198 
00199     return elementList[index].connectivity;
00200 }
00201 
00202 const std::vector< size_t >& MeshImplData::vertex_adjacencies( size_t index, MsqError& err ) const
00203 {
00204     if( !is_vertex_valid( index ) )
00205     {
00206         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00207         return dummy_list;
00208     }
00209 
00210     return vertexList[index].adjacencies;
00211 }
00212 
00213 void MeshImplData::clear()
00214 {
00215     vertexList.clear();
00216     elementList.clear();
00217     deletedVertexList.clear();
00218     deletedElementList.clear();
00219     haveSlavedFlags = false;
00220 }
00221 
00222 void MeshImplData::allocate_vertices( size_t count, MsqError& err )
00223 {
00224     if( vertexList.size() )
00225     {
00226         MSQ_SETERR( err )( MsqError::INVALID_STATE );
00227         return;
00228     }
00229 
00230     vertexList.resize( count );
00231 }
00232 
00233 void MeshImplData::allocate_elements( size_t count, MsqError& err )
00234 {
00235     if( elementList.size() )
00236     {
00237         MSQ_SETERR( err )( MsqError::INVALID_STATE );
00238         return;
00239     }
00240 
00241     elementList.resize( count );
00242 }
00243 
00244 void MeshImplData::set_vertex_coords( size_t index, const Vector3D& coords, MsqError& err )
00245 {
00246     if( !is_vertex_valid( index ) )
00247     {
00248         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00249         return;
00250     }
00251 
00252     vertexList[index].coords = coords;
00253 }
00254 
00255 void MeshImplData::reset_vertex( size_t index, const Vector3D& coords, bool fixed, MsqError& err )
00256 {
00257     if( index >= vertexList.size() )
00258     {
00259         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00260         return;
00261     }
00262 
00263     Vertex& vert = vertexList[index];
00264 
00265     if( !vert.adjacencies.empty() )
00266     {
00267         MSQ_SETERR( err )( "Cannot overwrite referenced vertex", MsqError::INVALID_STATE );
00268         return;
00269     }
00270 
00271     vert.coords = coords;
00272     vert.fixed  = fixed;
00273     vert.valid  = true;
00274 }
00275 
00276 void MeshImplData::reset_element( size_t index, const std::vector< long >& vertices, EntityTopology topology,
00277                                   MsqError& err )
00278 {
00279     clear_element( index, err );MSQ_ERRRTN( err );
00280     set_element( index, vertices, topology, err );MSQ_ERRRTN( err );
00281 }
00282 
00283 void MeshImplData::reset_element( size_t index, const std::vector< size_t >& vertices, EntityTopology topology,
00284                                   MsqError& err )
00285 {
00286     clear_element( index, err );MSQ_ERRRTN( err );
00287     set_element( index, vertices, topology, err );MSQ_ERRRTN( err );
00288 }
00289 
00290 void MeshImplData::clear_element( size_t index, MsqError& err )
00291 {
00292     if( index >= elementList.size() )
00293     {
00294         MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
00295         return;
00296     }
00297 
00298     unsigned numvert = TopologyInfo::corners( elementList[index].topology );
00299     if( numvert )
00300         for( unsigned i = numvert; i < elementList[index].connectivity.size(); ++i )
00301             --vertexList[elementList[index].connectivity[i]].midcount;
00302 
00303     std::vector< size_t >& conn = elementList[index].connectivity;
00304     for( std::vector< size_t >::iterator iter = conn.begin(); iter != conn.end(); ++iter )
00305     {
00306         std::vector< size_t >& adj = vertexList[*iter].adjacencies;
00307         for( std::vector< size_t >::iterator iter2 = adj.begin(); iter2 != adj.end(); ++iter2 )
00308         {
00309             if( *iter2 == index )
00310             {
00311                 adj.erase( iter2 );
00312                 break;
00313             }
00314         }
00315     }
00316     conn.clear();
00317 }
00318 
00319 void MeshImplData::set_element( size_t index, const std::vector< long >& vertices, EntityTopology topology,
00320                                 MsqError& err )
00321 {
00322     if( sizeof( long ) == sizeof( size_t ) )
00323         set_element( index, *reinterpret_cast< const std::vector< size_t >* >( &vertices ), topology, err );
00324     else
00325     {
00326         std::vector< size_t > conn( vertices.size() );
00327         std::copy( vertices.begin(), vertices.end(), conn.begin() );
00328         set_element( index, conn, topology, err );
00329     }
00330 }
00331 
00332 void MeshImplData::set_element( size_t index, const std::vector< size_t >& vertices, EntityTopology topology,
00333                                 MsqError& err )
00334 {
00335     if( index >= elementList.size() )
00336     {
00337         MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
00338         return;
00339     }
00340 
00341     elementList[index].connectivity = vertices;
00342     elementList[index].topology     = topology;
00343 
00344     for( std::vector< size_t >::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter )
00345     {
00346         if( !is_vertex_valid( *iter ) )
00347         {
00348             MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00349             return;
00350         }
00351 
00352         std::vector< size_t >& adj = vertexList[*iter].adjacencies;
00353         for( std::vector< size_t >::iterator iter2 = adj.begin(); iter2 != adj.end(); ++iter2 )
00354             if( *iter2 == index ) return;
00355 
00356         adj.push_back( index );
00357     }
00358 
00359     unsigned numvert = TopologyInfo::corners( elementList[index].topology );
00360     if( numvert )
00361         for( unsigned i = numvert; i < elementList[index].connectivity.size(); ++i )
00362             ++vertexList[elementList[index].connectivity[i]].midcount;
00363 }
00364 
00365 size_t MeshImplData::add_vertex( const Vector3D& coords, bool fixed, MsqError& err )
00366 {
00367     size_t index;
00368 
00369     if( !deletedVertexList.empty() )
00370     {
00371         index = deletedVertexList[deletedVertexList.size() - 1];
00372         deletedVertexList.pop_back();
00373         reset_vertex( index, coords, fixed, err );
00374         MSQ_ERRZERO( err );
00375     }
00376     else
00377     {
00378         index = vertexList.size();
00379         vertexList.push_back( Vertex( coords, fixed ) );
00380     }
00381 
00382     return index;
00383 }
00384 
00385 size_t MeshImplData::add_element( const std::vector< long >& vertices, EntityTopology topology, MsqError& err )
00386 {
00387     size_t index;
00388     if( !deletedElementList.empty() )
00389     {
00390         index = deletedElementList[deletedElementList.size() - 1];
00391         deletedElementList.pop_back();
00392     }
00393     else
00394     {
00395         index = elementList.size();
00396         elementList.resize( elementList.size() + 1 );
00397     }
00398 
00399     set_element( index, vertices, topology, err );
00400     MSQ_ERRZERO( err );
00401     return index;
00402 }
00403 
00404 size_t MeshImplData::add_element( const std::vector< size_t >& vertices, EntityTopology topology, MsqError& err )
00405 {
00406     size_t index;
00407     if( !deletedElementList.empty() )
00408     {
00409         index = deletedElementList[deletedElementList.size() - 1];
00410         deletedElementList.pop_back();
00411     }
00412     else
00413     {
00414         index = elementList.size();
00415         elementList.resize( elementList.size() + 1 );
00416     }
00417 
00418     set_element( index, vertices, topology, err );
00419     MSQ_ERRZERO( err );
00420     return index;
00421 }
00422 
00423 void MeshImplData::delete_vertex( size_t index, MsqError& err )
00424 {
00425     if( !is_vertex_valid( index ) )
00426     {
00427         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00428         return;
00429     }
00430 
00431     vertexList[index].valid = false;
00432     deletedVertexList.push_back( index );
00433 }
00434 
00435 void MeshImplData::delete_element( size_t index, MsqError& err )
00436 {
00437     clear_element( index, err );MSQ_ERRRTN( err );
00438     deletedElementList.push_back( index );
00439 }
00440 
00441 void MeshImplData::copy_mesh( size_t* vertex_handle_array, size_t* element_handle_array, size_t* element_conn_offsets,
00442                               size_t* element_conn_indices )
00443 {
00444     std::vector< size_t > vertex_map( vertexList.size() );
00445     size_t vh_index = 0;
00446     for( size_t v = 0; v < vertexList.size(); ++v )
00447     {
00448         if( vertexList[v].valid
00449 #ifdef SEPARATE_MID_NODES
00450             && vertexList[v].midcount < vertexList[v].adjacencies.size()
00451 #endif
00452         )
00453         {
00454             vertex_handle_array[vh_index] = v;
00455             vertex_map[v]                 = vh_index;
00456             ++vh_index;
00457         }
00458         else
00459         {
00460             vertex_map[v] = vertexList.size();
00461         }
00462     }
00463 
00464     size_t offset = 0;
00465     for( size_t e = 0; e < elementList.size(); ++e )
00466     {
00467         Element& elem = elementList[e];
00468         size_t cl;
00469 #ifdef SEPARATE_MID_NODES
00470         cl = TopologyInfo::corners( elem.topology );
00471         if( !cl )
00472 #endif
00473             cl = elem.connectivity.size();
00474         if( cl )
00475         {
00476             *element_handle_array = e;
00477             ++element_handle_array;
00478 
00479             *element_conn_offsets = offset;
00480             ++element_conn_offsets;
00481             offset += cl;
00482 
00483             std::vector< size_t >::iterator conn = elem.connectivity.begin();
00484             std::vector< size_t >::iterator end  = conn + cl;
00485             while( conn != end )
00486             {
00487                 *element_conn_indices = vertex_map[*conn];
00488                 ++element_conn_indices;
00489                 ++conn;
00490             }
00491         }
00492     }
00493     *element_conn_offsets = offset;
00494 }
00495 
00496 void MeshImplData::copy_higher_order( std::vector< size_t >& mid_nodes, std::vector< size_t >& vertices,
00497                                       std::vector< size_t >& vertex_indices, std::vector< size_t >& index_offsets,
00498                                       MsqError& err )
00499 {
00500     mid_nodes.clear();
00501     vertices.clear();
00502     vertex_indices.clear();
00503     index_offsets.clear();
00504 
00505     // Create a map of from vertex handle to index in "vertices"
00506     // Use vertexList.size() to mean uninitialized.
00507     size_t v;
00508     std::vector< size_t > vert_map( vertexList.size() );
00509     for( v = 0; v < vertexList.size(); ++v )
00510         vert_map[v] = vertexList.size();
00511 
00512     // Loop over all mid-side vertices
00513     for( v = 0; v < vertexList.size(); ++v )
00514     {
00515         const Vertex& vert = vertexList[v];
00516 
00517         // Not a mid-side vertex, skip it
00518         if( !vert.valid || !vert.midcount ) continue;
00519 
00520         // Populate "verts" with the handles of all adjacent corner vertices
00521         assert( vert.adjacencies.size() );  // shouldn't be able to fail if vert.midcount > 0
00522         int elem_indx = vert.adjacencies[0];
00523         Element& elem = elementList[elem_indx];
00524 
00525         // Find index of node in elem's connectivity list
00526         unsigned index;
00527         for( index = 0; index < elem.connectivity.size(); ++index )
00528             if( elem.connectivity[index] == v ) break;
00529         if( index == elem.connectivity.size() )
00530         {
00531             MSQ_SETERR( err )( "Inconsistent data.", MsqError::INTERNAL_ERROR );
00532             return;
00533         }
00534 
00535         // Given the index in the element's connectivity list,
00536         // get the side of the element containing the mid-node.
00537         unsigned side_dim, side_num;
00538         TopologyInfo::side_number( elem.topology, elem.connectivity.size(), index, side_dim, side_num, err );MSQ_ERRRTN( err );
00539 
00540         if( !side_dim )  // Not a mid-side node
00541         {
00542             MSQ_SETERR( err )( MsqError::INVALID_STATE, "Improperly connected mesh." );
00543             return;
00544         }
00545 
00546         // Get the adjacent corner vertices from the element side.
00547         unsigned num_corners;
00548         const unsigned* corner_indices =
00549             TopologyInfo::side_vertices( elem.topology, side_dim, side_num, num_corners, err );MSQ_ERRRTN( err );
00550 
00551         // Add the mid-side node to the output list
00552         mid_nodes.push_back( v );
00553         // Store offset at which the indices of the corner
00554         // vertices adjacent to this mid-side node will be
00555         // stored in "vertex_indices".
00556         index_offsets.push_back( vertex_indices.size() );
00557         // For each adjacent corner vertex, if the vertex is not
00558         // already in "vertices" add it, and add the index to
00559         // the adjacency list for this mid-side node.
00560         for( unsigned i = 0; i < num_corners; ++i )
00561         {
00562             size_t vert_idx = elem.connectivity[corner_indices[i]];
00563             assert( is_vertex_valid( vert_idx ) );
00564 
00565             if( vert_map[vert_idx] == vertexList.size() )
00566             {
00567                 vert_map[vert_idx] = vertices.size();
00568                 vertices.push_back( vert_idx );
00569             }
00570             vertex_indices.push_back( vert_map[vert_idx] );
00571         }
00572     }
00573     index_offsets.push_back( vertex_indices.size() );
00574 }
00575 
00576 bool MeshImplData::is_mid_node( size_t index ) const
00577 {
00578     return is_vertex_valid( index ) && vertexList[index].midcount > 0;
00579 }
00580 
00581 bool MeshImplData::is_corner_node( size_t index ) const
00582 {
00583     return is_vertex_valid( index ) && vertexList[index].midcount < vertexList[index].adjacencies.size();
00584 }
00585 
00586 void MeshImplData::all_vertices( std::vector< size_t >& list, MsqError& ) const
00587 {
00588     list.clear();
00589     for( size_t idx = 0; idx < vertexList.size(); ++idx )
00590         if( vertexList[idx].valid ) list.push_back( idx );
00591 }
00592 
00593 void MeshImplData::all_elements( std::vector< size_t >& list, MsqError& ) const
00594 {
00595     list.clear();
00596     for( size_t idx = 0; idx < elementList.size(); ++idx )
00597         if( !elementList[idx].connectivity.empty() ) list.push_back( idx );
00598 }
00599 
00600 void MeshImplData::get_adjacent_elements( std::vector< size_t >::const_iterator node_iter,
00601                                           std::vector< size_t >::const_iterator node_end, std::vector< size_t >& elems,
00602                                           MsqError& err )
00603 {
00604     if( node_iter == node_end || !is_vertex_valid( *node_iter ) )
00605     {
00606         MSQ_SETERR( err )( MsqError::INVALID_ARG );
00607         return;
00608     }
00609 
00610     // Get list of elements adjacent to first node
00611     elems = vertexList[*node_iter].adjacencies;
00612 
00613     // For each aditional node, intersect elems with elements adjacent to node
00614     for( ++node_iter; node_iter != node_end; ++node_iter )
00615     {
00616         std::vector< size_t >::iterator elem_iter = elems.begin();
00617         while( elem_iter != elems.end() )
00618         {
00619             std::vector< size_t >::const_iterator adj_iter      = vertexList[*node_iter].adjacencies.begin();
00620             const std::vector< size_t >::const_iterator adj_end = vertexList[*node_iter].adjacencies.end();
00621             for( ; adj_iter != adj_end; ++adj_iter )
00622                 if( *elem_iter == *adj_iter ) break;
00623 
00624             if( adj_iter == adj_end )
00625             {
00626                 *elem_iter = elems[elems.size() - 1];
00627                 elems.pop_back();
00628             }
00629             else
00630             {
00631                 ++elem_iter;
00632             }
00633         }
00634     }
00635 }
00636 
00637 bool MeshImplData::has_adjacent_elements( size_t elem, const std::vector< size_t >& nodes, MsqError& err )
00638 {
00639     std::vector< size_t > adj_elems;
00640     const unsigned dim = TopologyInfo::dimension( elementList[elem].topology );
00641     get_adjacent_elements( nodes.begin(), nodes.end(), adj_elems, err );
00642 
00643     std::vector< size_t >::iterator iter;
00644     for( iter = adj_elems.begin(); iter != adj_elems.end(); ++iter )
00645         if( *iter != elem && TopologyInfo::dimension( elementList[*iter].topology ) == dim ) break;
00646 
00647     return iter != adj_elems.end();
00648 }
00649 
00650 void MeshImplData::skin( std::vector< size_t >& sides, MsqError& err )
00651 {
00652     std::vector< size_t > side_nodes;
00653 
00654     // For each element in mesh
00655     for( size_t elem = 0; elem < elementList.size(); ++elem )
00656     {
00657         if( !is_element_valid( elem ) ) continue;
00658 
00659         // For each side of the element, check if there
00660         // are any adjacent elements.
00661         const EntityTopology topo   = elementList[elem].topology;
00662         std::vector< size_t >& conn = elementList[elem].connectivity;
00663         switch( topo )
00664         {
00665                 // For normal elements (not poly****)
00666             default: {
00667                 unsigned num = TopologyInfo::sides( topo );
00668                 unsigned dim = TopologyInfo::dimension( topo ) - 1;
00669                 // For each side
00670                 for( unsigned side = 0; side < num; ++side )
00671                 {
00672                     // Get list of vertices defining the side
00673                     unsigned count;
00674                     const unsigned* indices = TopologyInfo::side_vertices( topo, dim, side, count, err );MSQ_ERRRTN( err );
00675                     side_nodes.clear();
00676                     for( unsigned k = 0; k < count; ++k )
00677                         side_nodes.push_back( conn[indices[k]] );
00678 
00679                     // If no adjacent element, add side to output list
00680                     bool adj = has_adjacent_elements( elem, side_nodes, err );MSQ_ERRRTN( err );
00681                     if( !adj )
00682                     {
00683                         sides.push_back( elem );
00684                         sides.push_back( side );
00685                     }
00686                 }
00687             }
00688             break;
00689 
00690             case POLYGON: {
00691                 for( unsigned side = 0, next = 1; next < conn.size(); ++side, ++next )
00692                 {
00693                     side_nodes.clear();
00694                     side_nodes.push_back( conn[side] );
00695                     side_nodes.push_back( conn[next] );
00696 
00697                     // If no adjacent element, add side to output list
00698                     bool adj = has_adjacent_elements( elem, side_nodes, err );MSQ_ERRRTN( err );
00699                     if( !adj )
00700                     {
00701                         sides.push_back( elem );
00702                         sides.push_back( side );
00703                     }
00704                 }
00705             }
00706             break;
00707 
00708             case POLYHEDRON: {
00709                 for( unsigned side = 0; side < conn.size(); ++side )
00710                 {
00711                     side_nodes = elementList[conn[side]].connectivity;
00712 
00713                     // If no adjacent element, add side to output list
00714                     bool adj = has_adjacent_elements( elem, side_nodes, err );MSQ_ERRRTN( err );
00715                     if( !adj )
00716                     {
00717                         sides.push_back( elem );
00718                         sides.push_back( side );
00719                     }
00720                 }
00721             }
00722             break;
00723         }  // switch(topo)
00724     }      // for (elementList)
00725 }
00726 
00727 MeshImplVertIter::~MeshImplVertIter() {}
00728 
00729 void MeshImplVertIter::restart()
00730 {
00731     index = 0;
00732     if( !mesh->is_vertex_valid( index ) ) operator++();
00733 }
00734 
00735 void MeshImplVertIter::operator++()
00736 {
00737     ++index;
00738     while( index < mesh->max_vertex_index() && ( !mesh->is_vertex_valid( index ) || !mesh->is_corner_node( index ) ) )
00739         ++index;
00740 }
00741 
00742 Mesh::VertexHandle MeshImplVertIter::operator*() const
00743 {
00744     return reinterpret_cast< Mesh::VertexHandle >( index );
00745 }
00746 
00747 bool MeshImplVertIter::is_at_end() const
00748 {
00749     return index >= mesh->max_vertex_index();
00750 }
00751 
00752 MeshImplElemIter::~MeshImplElemIter() {}
00753 
00754 void MeshImplElemIter::restart()
00755 {
00756     index = 0;
00757     if( !mesh->is_element_valid( index ) ) operator++();
00758 }
00759 
00760 void MeshImplElemIter::operator++()
00761 {
00762     ++index;
00763     while( index < mesh->max_element_index() && !mesh->is_element_valid( index ) )
00764         ++index;
00765 }
00766 
00767 Mesh::ElementHandle MeshImplElemIter::operator*() const
00768 {
00769     return reinterpret_cast< Mesh::ElementHandle >( index );
00770 }
00771 
00772 bool MeshImplElemIter::is_at_end() const
00773 {
00774     return index >= mesh->max_element_index();
00775 }
00776 
00777 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines