MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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