MOAB: Mesh Oriented datABase  (version 5.4.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     [email protected]
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,
00277                                   const std::vector< long >& vertices,
00278                                   EntityTopology topology,
00279                                   MsqError& err )
00280 {
00281     clear_element( index, err );MSQ_ERRRTN( err );
00282     set_element( index, vertices, topology, err );MSQ_ERRRTN( err );
00283 }
00284 
00285 void MeshImplData::reset_element( size_t index,
00286                                   const std::vector< size_t >& vertices,
00287                                   EntityTopology topology,
00288                                   MsqError& err )
00289 {
00290     clear_element( index, err );MSQ_ERRRTN( err );
00291     set_element( index, vertices, topology, err );MSQ_ERRRTN( err );
00292 }
00293 
00294 void MeshImplData::clear_element( size_t index, MsqError& err )
00295 {
00296     if( index >= elementList.size() )
00297     {
00298         MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
00299         return;
00300     }
00301 
00302     unsigned numvert = TopologyInfo::corners( elementList[index].topology );
00303     if( numvert )
00304         for( unsigned i = numvert; i < elementList[index].connectivity.size(); ++i )
00305             --vertexList[elementList[index].connectivity[i]].midcount;
00306 
00307     std::vector< size_t >& conn = elementList[index].connectivity;
00308     for( std::vector< size_t >::iterator iter = conn.begin(); iter != conn.end(); ++iter )
00309     {
00310         std::vector< size_t >& adj = vertexList[*iter].adjacencies;
00311         for( std::vector< size_t >::iterator iter2 = adj.begin(); iter2 != adj.end(); ++iter2 )
00312         {
00313             if( *iter2 == index )
00314             {
00315                 adj.erase( iter2 );
00316                 break;
00317             }
00318         }
00319     }
00320     conn.clear();
00321 }
00322 
00323 void MeshImplData::set_element( size_t index,
00324                                 const std::vector< long >& vertices,
00325                                 EntityTopology topology,
00326                                 MsqError& err )
00327 {
00328     if( sizeof( long ) == sizeof( size_t ) )
00329         set_element( index, *reinterpret_cast< const std::vector< size_t >* >( &vertices ), topology, err );
00330     else
00331     {
00332         std::vector< size_t > conn( vertices.size() );
00333         std::copy( vertices.begin(), vertices.end(), conn.begin() );
00334         set_element( index, conn, topology, err );
00335     }
00336 }
00337 
00338 void MeshImplData::set_element( size_t index,
00339                                 const std::vector< size_t >& vertices,
00340                                 EntityTopology topology,
00341                                 MsqError& err )
00342 {
00343     if( index >= elementList.size() )
00344     {
00345         MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
00346         return;
00347     }
00348 
00349     elementList[index].connectivity = vertices;
00350     elementList[index].topology     = topology;
00351 
00352     for( std::vector< size_t >::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter )
00353     {
00354         if( !is_vertex_valid( *iter ) )
00355         {
00356             MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00357             return;
00358         }
00359 
00360         std::vector< size_t >& adj = vertexList[*iter].adjacencies;
00361         for( std::vector< size_t >::iterator iter2 = adj.begin(); iter2 != adj.end(); ++iter2 )
00362             if( *iter2 == index ) return;
00363 
00364         adj.push_back( index );
00365     }
00366 
00367     unsigned numvert = TopologyInfo::corners( elementList[index].topology );
00368     if( numvert )
00369         for( unsigned i = numvert; i < elementList[index].connectivity.size(); ++i )
00370             ++vertexList[elementList[index].connectivity[i]].midcount;
00371 }
00372 
00373 size_t MeshImplData::add_vertex( const Vector3D& coords, bool fixed, MsqError& err )
00374 {
00375     size_t index;
00376 
00377     if( !deletedVertexList.empty() )
00378     {
00379         index = deletedVertexList[deletedVertexList.size() - 1];
00380         deletedVertexList.pop_back();
00381         reset_vertex( index, coords, fixed, err );
00382         MSQ_ERRZERO( err );
00383     }
00384     else
00385     {
00386         index = vertexList.size();
00387         vertexList.push_back( Vertex( coords, fixed ) );
00388     }
00389 
00390     return index;
00391 }
00392 
00393 size_t MeshImplData::add_element( const std::vector< long >& vertices, EntityTopology topology, MsqError& err )
00394 {
00395     size_t index;
00396     if( !deletedElementList.empty() )
00397     {
00398         index = deletedElementList[deletedElementList.size() - 1];
00399         deletedElementList.pop_back();
00400     }
00401     else
00402     {
00403         index = elementList.size();
00404         elementList.resize( elementList.size() + 1 );
00405     }
00406 
00407     set_element( index, vertices, topology, err );
00408     MSQ_ERRZERO( err );
00409     return index;
00410 }
00411 
00412 size_t MeshImplData::add_element( const std::vector< size_t >& vertices, EntityTopology topology, MsqError& err )
00413 {
00414     size_t index;
00415     if( !deletedElementList.empty() )
00416     {
00417         index = deletedElementList[deletedElementList.size() - 1];
00418         deletedElementList.pop_back();
00419     }
00420     else
00421     {
00422         index = elementList.size();
00423         elementList.resize( elementList.size() + 1 );
00424     }
00425 
00426     set_element( index, vertices, topology, err );
00427     MSQ_ERRZERO( err );
00428     return index;
00429 }
00430 
00431 void MeshImplData::delete_vertex( size_t index, MsqError& err )
00432 {
00433     if( !is_vertex_valid( index ) )
00434     {
00435         MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
00436         return;
00437     }
00438 
00439     vertexList[index].valid = false;
00440     deletedVertexList.push_back( index );
00441 }
00442 
00443 void MeshImplData::delete_element( size_t index, MsqError& err )
00444 {
00445     clear_element( index, err );MSQ_ERRRTN( err );
00446     deletedElementList.push_back( index );
00447 }
00448 
00449 void MeshImplData::copy_mesh( size_t* vertex_handle_array,
00450                               size_t* element_handle_array,
00451                               size_t* element_conn_offsets,
00452                               size_t* element_conn_indices )
00453 {
00454     std::vector< size_t > vertex_map( vertexList.size() );
00455     size_t vh_index = 0;
00456     for( size_t v = 0; v < vertexList.size(); ++v )
00457     {
00458         if( vertexList[v].valid
00459 #ifdef SEPARATE_MID_NODES
00460             && vertexList[v].midcount < vertexList[v].adjacencies.size()
00461 #endif
00462         )
00463         {
00464             vertex_handle_array[vh_index] = v;
00465             vertex_map[v]                 = vh_index;
00466             ++vh_index;
00467         }
00468         else
00469         {
00470             vertex_map[v] = vertexList.size();
00471         }
00472     }
00473 
00474     size_t offset = 0;
00475     for( size_t e = 0; e < elementList.size(); ++e )
00476     {
00477         Element& elem = elementList[e];
00478         size_t cl;
00479 #ifdef SEPARATE_MID_NODES
00480         cl = TopologyInfo::corners( elem.topology );
00481         if( !cl )
00482 #endif
00483             cl = elem.connectivity.size();
00484         if( cl )
00485         {
00486             *element_handle_array = e;
00487             ++element_handle_array;
00488 
00489             *element_conn_offsets = offset;
00490             ++element_conn_offsets;
00491             offset += cl;
00492 
00493             std::vector< size_t >::iterator conn = elem.connectivity.begin();
00494             std::vector< size_t >::iterator end  = conn + cl;
00495             while( conn != end )
00496             {
00497                 *element_conn_indices = vertex_map[*conn];
00498                 ++element_conn_indices;
00499                 ++conn;
00500             }
00501         }
00502     }
00503     *element_conn_offsets = offset;
00504 }
00505 
00506 void MeshImplData::copy_higher_order( std::vector< size_t >& mid_nodes,
00507                                       std::vector< size_t >& vertices,
00508                                       std::vector< size_t >& vertex_indices,
00509                                       std::vector< size_t >& index_offsets,
00510                                       MsqError& err )
00511 {
00512     mid_nodes.clear();
00513     vertices.clear();
00514     vertex_indices.clear();
00515     index_offsets.clear();
00516 
00517     // Create a map of from vertex handle to index in "vertices"
00518     // Use vertexList.size() to mean uninitialized.
00519     size_t v;
00520     std::vector< size_t > vert_map( vertexList.size() );
00521     for( v = 0; v < vertexList.size(); ++v )
00522         vert_map[v] = vertexList.size();
00523 
00524     // Loop over all mid-side vertices
00525     for( v = 0; v < vertexList.size(); ++v )
00526     {
00527         const Vertex& vert = vertexList[v];
00528 
00529         // Not a mid-side vertex, skip it
00530         if( !vert.valid || !vert.midcount ) continue;
00531 
00532         // Populate "verts" with the handles of all adjacent corner vertices
00533         assert( vert.adjacencies.size() );  // shouldn't be able to fail if vert.midcount > 0
00534         int elem_indx = vert.adjacencies[0];
00535         Element& elem = elementList[elem_indx];
00536 
00537         // Find index of node in elem's connectivity list
00538         unsigned index;
00539         for( index = 0; index < elem.connectivity.size(); ++index )
00540             if( elem.connectivity[index] == v ) break;
00541         if( index == elem.connectivity.size() )
00542         {
00543             MSQ_SETERR( err )( "Inconsistent data.", MsqError::INTERNAL_ERROR );
00544             return;
00545         }
00546 
00547         // Given the index in the element's connectivity list,
00548         // get the side of the element containing the mid-node.
00549         unsigned side_dim, side_num;
00550         TopologyInfo::side_number( elem.topology, elem.connectivity.size(), index, side_dim, side_num, err );MSQ_ERRRTN( err );
00551 
00552         if( !side_dim )  // Not a mid-side node
00553         {
00554             MSQ_SETERR( err )( MsqError::INVALID_STATE, "Improperly connected mesh." );
00555             return;
00556         }
00557 
00558         // Get the adjacent corner vertices from the element side.
00559         unsigned num_corners;
00560         const unsigned* corner_indices =
00561             TopologyInfo::side_vertices( elem.topology, side_dim, side_num, num_corners, err );MSQ_ERRRTN( err );
00562 
00563         // Add the mid-side node to the output list
00564         mid_nodes.push_back( v );
00565         // Store offset at which the indices of the corner
00566         // vertices adjacent to this mid-side node will be
00567         // stored in "vertex_indices".
00568         index_offsets.push_back( vertex_indices.size() );
00569         // For each adjacent corner vertex, if the vertex is not
00570         // already in "vertices" add it, and add the index to
00571         // the adjacency list for this mid-side node.
00572         for( unsigned i = 0; i < num_corners; ++i )
00573         {
00574             size_t vert_idx = elem.connectivity[corner_indices[i]];
00575             assert( is_vertex_valid( vert_idx ) );
00576 
00577             if( vert_map[vert_idx] == vertexList.size() )
00578             {
00579                 vert_map[vert_idx] = vertices.size();
00580                 vertices.push_back( vert_idx );
00581             }
00582             vertex_indices.push_back( vert_map[vert_idx] );
00583         }
00584     }
00585     index_offsets.push_back( vertex_indices.size() );
00586 }
00587 
00588 bool MeshImplData::is_mid_node( size_t index ) const
00589 {
00590     return is_vertex_valid( index ) && vertexList[index].midcount > 0;
00591 }
00592 
00593 bool MeshImplData::is_corner_node( size_t index ) const
00594 {
00595     return is_vertex_valid( index ) && vertexList[index].midcount < vertexList[index].adjacencies.size();
00596 }
00597 
00598 void MeshImplData::all_vertices( std::vector< size_t >& list, MsqError& ) const
00599 {
00600     list.clear();
00601     for( size_t idx = 0; idx < vertexList.size(); ++idx )
00602         if( vertexList[idx].valid ) list.push_back( idx );
00603 }
00604 
00605 void MeshImplData::all_elements( std::vector< size_t >& list, MsqError& ) const
00606 {
00607     list.clear();
00608     for( size_t idx = 0; idx < elementList.size(); ++idx )
00609         if( !elementList[idx].connectivity.empty() ) list.push_back( idx );
00610 }
00611 
00612 void MeshImplData::get_adjacent_elements( std::vector< size_t >::const_iterator node_iter,
00613                                           std::vector< size_t >::const_iterator node_end,
00614                                           std::vector< size_t >& elems,
00615                                           MsqError& err )
00616 {
00617     if( node_iter == node_end || !is_vertex_valid( *node_iter ) )
00618     {
00619         MSQ_SETERR( err )( MsqError::INVALID_ARG );
00620         return;
00621     }
00622 
00623     // Get list of elements adjacent to first node
00624     elems = vertexList[*node_iter].adjacencies;
00625 
00626     // For each aditional node, intersect elems with elements adjacent to node
00627     for( ++node_iter; node_iter != node_end; ++node_iter )
00628     {
00629         std::vector< size_t >::iterator elem_iter = elems.begin();
00630         while( elem_iter != elems.end() )
00631         {
00632             std::vector< size_t >::const_iterator adj_iter      = vertexList[*node_iter].adjacencies.begin();
00633             const std::vector< size_t >::const_iterator adj_end = vertexList[*node_iter].adjacencies.end();
00634             for( ; adj_iter != adj_end; ++adj_iter )
00635                 if( *elem_iter == *adj_iter ) break;
00636 
00637             if( adj_iter == adj_end )
00638             {
00639                 *elem_iter = elems[elems.size() - 1];
00640                 elems.pop_back();
00641             }
00642             else
00643             {
00644                 ++elem_iter;
00645             }
00646         }
00647     }
00648 }
00649 
00650 bool MeshImplData::has_adjacent_elements( size_t elem, const std::vector< size_t >& nodes, MsqError& err )
00651 {
00652     std::vector< size_t > adj_elems;
00653     const unsigned dim = TopologyInfo::dimension( elementList[elem].topology );
00654     get_adjacent_elements( nodes.begin(), nodes.end(), adj_elems, err );
00655 
00656     std::vector< size_t >::iterator iter;
00657     for( iter = adj_elems.begin(); iter != adj_elems.end(); ++iter )
00658         if( *iter != elem && TopologyInfo::dimension( elementList[*iter].topology ) == dim ) break;
00659 
00660     return iter != adj_elems.end();
00661 }
00662 
00663 void MeshImplData::skin( std::vector< size_t >& sides, MsqError& err )
00664 {
00665     std::vector< size_t > side_nodes;
00666 
00667     // For each element in mesh
00668     for( size_t elem = 0; elem < elementList.size(); ++elem )
00669     {
00670         if( !is_element_valid( elem ) ) continue;
00671 
00672         // For each side of the element, check if there
00673         // are any adjacent elements.
00674         const EntityTopology topo   = elementList[elem].topology;
00675         std::vector< size_t >& conn = elementList[elem].connectivity;
00676         switch( topo )
00677         {
00678                 // For normal elements (not poly****)
00679             default: {
00680                 unsigned num = TopologyInfo::sides( topo );
00681                 unsigned dim = TopologyInfo::dimension( topo ) - 1;
00682                 // For each side
00683                 for( unsigned side = 0; side < num; ++side )
00684                 {
00685                     // Get list of vertices defining the side
00686                     unsigned count;
00687                     const unsigned* indices = TopologyInfo::side_vertices( topo, dim, side, count, err );MSQ_ERRRTN( err );
00688                     side_nodes.clear();
00689                     for( unsigned k = 0; k < count; ++k )
00690                         side_nodes.push_back( conn[indices[k]] );
00691 
00692                     // If no adjacent element, add side to output list
00693                     bool adj = has_adjacent_elements( elem, side_nodes, err );MSQ_ERRRTN( err );
00694                     if( !adj )
00695                     {
00696                         sides.push_back( elem );
00697                         sides.push_back( side );
00698                     }
00699                 }
00700             }
00701             break;
00702 
00703             case POLYGON: {
00704                 for( unsigned side = 0, next = 1; next < conn.size(); ++side, ++next )
00705                 {
00706                     side_nodes.clear();
00707                     side_nodes.push_back( conn[side] );
00708                     side_nodes.push_back( conn[next] );
00709 
00710                     // If no adjacent element, add side to output list
00711                     bool adj = has_adjacent_elements( elem, side_nodes, err );MSQ_ERRRTN( err );
00712                     if( !adj )
00713                     {
00714                         sides.push_back( elem );
00715                         sides.push_back( side );
00716                     }
00717                 }
00718             }
00719             break;
00720 
00721             case POLYHEDRON: {
00722                 for( unsigned side = 0; side < conn.size(); ++side )
00723                 {
00724                     side_nodes = elementList[conn[side]].connectivity;
00725 
00726                     // If no adjacent element, add side to output list
00727                     bool adj = has_adjacent_elements( elem, side_nodes, err );MSQ_ERRRTN( err );
00728                     if( !adj )
00729                     {
00730                         sides.push_back( elem );
00731                         sides.push_back( side );
00732                     }
00733                 }
00734             }
00735             break;
00736         }  // switch(topo)
00737     }      // for (elementList)
00738 }
00739 
00740 MeshImplVertIter::~MeshImplVertIter() {}
00741 
00742 void MeshImplVertIter::restart()
00743 {
00744     index = 0;
00745     if( !mesh->is_vertex_valid( index ) ) operator++();
00746 }
00747 
00748 void MeshImplVertIter::operator++()
00749 {
00750     ++index;
00751     while( index < mesh->max_vertex_index() && ( !mesh->is_vertex_valid( index ) || !mesh->is_corner_node( index ) ) )
00752         ++index;
00753 }
00754 
00755 Mesh::VertexHandle MeshImplVertIter::operator*() const
00756 {
00757     return reinterpret_cast< Mesh::VertexHandle >( index );
00758 }
00759 
00760 bool MeshImplVertIter::is_at_end() const
00761 {
00762     return index >= mesh->max_vertex_index();
00763 }
00764 
00765 MeshImplElemIter::~MeshImplElemIter() {}
00766 
00767 void MeshImplElemIter::restart()
00768 {
00769     index = 0;
00770     if( !mesh->is_element_valid( index ) ) operator++();
00771 }
00772 
00773 void MeshImplElemIter::operator++()
00774 {
00775     ++index;
00776     while( index < mesh->max_element_index() && !mesh->is_element_valid( index ) )
00777         ++index;
00778 }
00779 
00780 Mesh::ElementHandle MeshImplElemIter::operator*() const
00781 {
00782     return reinterpret_cast< Mesh::ElementHandle >( index );
00783 }
00784 
00785 bool MeshImplElemIter::is_at_end() const
00786 {
00787     return index >= mesh->max_element_index();
00788 }
00789 
00790 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines