Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain 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 */ 00015 00016 #include "moab/HalfFacetRep.hpp" 00017 #include "Internals.hpp" 00018 #include <iostream> 00019 #include <cassert> 00020 #include <vector> 00021 #include <map> 00022 #include "MBTagConventions.hpp" 00023 #include "moab/ScdInterface.hpp" 00024 #ifdef MOAB_HAVE_MPI 00025 #include "moab/ParallelComm.hpp" 00026 #endif 00027 00028 namespace moab 00029 { 00030 00031 inline EntityHandle CREATE_HALFFACET( const unsigned lid, const EntityID id ) 00032 { 00033 assert( id <= MB_END_ID && lid < 6 ); 00034 return ( ( (HFacet)lid ) << MB_ID_WIDTH ) | id; 00035 } 00036 inline EntityID FID_FROM_HALFFACET( HFacet handle ) 00037 { 00038 return ( handle & MB_ID_MASK ); 00039 } 00040 inline int LID_FROM_HALFFACET( HFacet handle ) 00041 { 00042 return static_cast< int >( handle >> MB_ID_WIDTH ); 00043 } 00044 00045 HalfFacetRep::HalfFacetRep( Core* impl, ParallelComm* comm, moab::EntityHandle rset, bool filter_ghosts ) 00046 : thismeshtype( CURVE ), mb( impl ), pcomm( comm ), _rset( rset ), _filterghost( filter_ghosts ) 00047 { 00048 assert( NULL != impl ); 00049 mInitAHFmaps = false; 00050 chk_mixed = false; 00051 is_mixed = false; 00052 } 00053 00054 HalfFacetRep::~HalfFacetRep() {} 00055 00056 MESHTYPE HalfFacetRep::get_mesh_type( int nverts, int nedges, int nfaces, int ncells ) 00057 { 00058 MESHTYPE mesh_type = CURVE; 00059 00060 if( nverts && nedges && ( !nfaces ) && ( !ncells ) ) 00061 mesh_type = CURVE; 00062 else if( nverts && !nedges && nfaces && !ncells ) 00063 mesh_type = SURFACE; 00064 else if( nverts && nedges && nfaces && !ncells ) 00065 mesh_type = SURFACE_MIXED; 00066 else if( nverts && !nedges && !nfaces && ncells ) 00067 mesh_type = VOLUME; 00068 else if( nverts && nedges && !nfaces && ncells ) 00069 mesh_type = VOLUME_MIXED_1; 00070 else if( nverts && !nedges && nfaces && ncells ) 00071 mesh_type = VOLUME_MIXED_2; 00072 else if( nverts && nedges && nfaces && ncells ) 00073 mesh_type = VOLUME_MIXED; 00074 00075 return mesh_type; 00076 } 00077 00078 const HalfFacetRep::adj_matrix HalfFacetRep::adjMatrix[7] = { 00079 // Stores the adjacency matrix for each mesh type. 00080 // CURVE 00081 { { { 0, 1, 0, 0 }, { 1, 1, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } } }, 00082 00083 // SURFACE 00084 { { { 0, 0, 1, 0 }, { 0, 0, 0, 0 }, { 1, 0, 1, 0 }, { 0, 0, 0, 0 } } }, 00085 00086 // SURFACE_MIXED 00087 { { { 0, 1, 1, 0 }, { 1, 1, 1, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 } } }, 00088 00089 // VOLUME 00090 { { { 0, 0, 0, 1 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 0, 0, 1 } } }, 00091 00092 // VOLUME_MIXED_1 00093 { { { 0, 1, 0, 1 }, { 1, 1, 0, 1 }, { 0, 0, 0, 0 }, { 1, 1, 0, 1 } } }, 00094 00095 // VOLUME_MIXED_2 00096 { { { 0, 0, 1, 1 }, { 0, 0, 0, 0 }, { 1, 0, 1, 1 }, { 1, 0, 1, 1 } } }, 00097 00098 // VOLUME_MIXED 00099 { { { 0, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 } } } }; 00100 00101 int HalfFacetRep::get_index_for_meshtype( MESHTYPE mesh_type ) 00102 { 00103 int index = 0; 00104 switch( mesh_type ) 00105 { 00106 case CURVE: 00107 index = 0; 00108 break; 00109 case SURFACE: 00110 index = 1; 00111 break; 00112 case SURFACE_MIXED: 00113 index = 2; 00114 break; 00115 case VOLUME: 00116 index = 3; 00117 break; 00118 case VOLUME_MIXED_1: 00119 index = 4; 00120 break; 00121 case VOLUME_MIXED_2: 00122 index = 5; 00123 break; 00124 case VOLUME_MIXED: 00125 index = 6; 00126 break; 00127 } 00128 return index; 00129 } 00130 00131 bool HalfFacetRep::check_mixed_entity_type() 00132 { 00133 if( !chk_mixed ) 00134 { 00135 chk_mixed = true; 00136 00137 ErrorCode error; 00138 Range felems, celems; 00139 00140 error = mb->get_entities_by_dimension( this->_rset, 2, felems );MB_CHK_ERR( error ); 00141 00142 if( felems.size() ) 00143 { 00144 Range tris, quad, poly; 00145 tris = felems.subset_by_type( MBTRI ); 00146 quad = felems.subset_by_type( MBQUAD ); 00147 poly = felems.subset_by_type( MBPOLYGON ); 00148 if( ( tris.size() && quad.size() ) || ( tris.size() && poly.size() ) || ( quad.size() && poly.size() ) ) 00149 is_mixed = true; 00150 if( poly.size() ) is_mixed = true; 00151 00152 if( is_mixed ) return is_mixed; 00153 } 00154 00155 error = mb->get_entities_by_dimension( this->_rset, 3, celems );MB_CHK_ERR( error ); 00156 if( celems.size() ) 00157 { 00158 Range tet, pyr, prism, hex, polyhed; 00159 tet = celems.subset_by_type( MBTET ); 00160 pyr = celems.subset_by_type( MBPYRAMID ); 00161 prism = celems.subset_by_type( MBPRISM ); 00162 hex = celems.subset_by_type( MBHEX ); 00163 polyhed = celems.subset_by_type( MBPOLYHEDRON ); 00164 if( ( tet.size() && pyr.size() ) || ( tet.size() && prism.size() ) || ( tet.size() && hex.size() ) || 00165 ( tet.size() && polyhed.size() ) || ( pyr.size() && prism.size() ) || ( pyr.size() && hex.size() ) || 00166 ( pyr.size() && polyhed.size() ) || ( prism.size() && hex.size() ) || 00167 ( prism.size() && polyhed.size() ) || ( hex.size() && polyhed.size() ) ) 00168 is_mixed = true; 00169 00170 if( polyhed.size() ) is_mixed = true; 00171 } 00172 00173 ScdInterface* scdi = NULL; 00174 error = mb->query_interface( scdi );MB_CHK_ERR( error ); 00175 if( scdi ) 00176 { 00177 Range boxes; 00178 error = scdi->find_boxes( boxes );MB_CHK_ERR( error ); 00179 00180 if( !boxes.empty() ) is_mixed = true; 00181 } 00182 } 00183 return is_mixed; 00184 } 00185 00186 /******************************************************* 00187 * initialize * 00188 ******************************************************/ 00189 00190 ErrorCode HalfFacetRep::initialize() 00191 { 00192 ErrorCode error; 00193 00194 if( !mInitAHFmaps ) 00195 { 00196 mInitAHFmaps = true; 00197 #ifdef MOAB_HAVE_MPI 00198 if( pcomm && _filterghost ) 00199 { 00200 moab::Range _averts, _aedgs, _afacs, _acels; 00201 error = mb->get_entities_by_dimension( this->_rset, 0, _averts, true );MB_CHK_ERR( error ); 00202 error = mb->get_entities_by_dimension( this->_rset, 1, _aedgs, true );MB_CHK_ERR( error ); 00203 error = mb->get_entities_by_dimension( this->_rset, 2, _afacs, true );MB_CHK_ERR( error ); 00204 error = mb->get_entities_by_dimension( this->_rset, 3, _acels, true );MB_CHK_ERR( error ); 00205 00206 // filter based on parallel status 00207 error = pcomm->filter_pstatus( _averts, PSTATUS_GHOST, PSTATUS_NOT, -1, &_verts );MB_CHK_ERR( error ); 00208 error = pcomm->filter_pstatus( _aedgs, PSTATUS_GHOST, PSTATUS_NOT, -1, &_edges );MB_CHK_ERR( error ); 00209 error = pcomm->filter_pstatus( _afacs, PSTATUS_GHOST, PSTATUS_NOT, -1, &_faces );MB_CHK_ERR( error ); 00210 error = pcomm->filter_pstatus( _acels, PSTATUS_GHOST, PSTATUS_NOT, -1, &_cells );MB_CHK_ERR( error ); 00211 } 00212 else 00213 { 00214 error = mb->get_entities_by_dimension( this->_rset, 0, _verts, true );MB_CHK_ERR( error ); 00215 error = mb->get_entities_by_dimension( this->_rset, 1, _edges, true );MB_CHK_ERR( error ); 00216 error = mb->get_entities_by_dimension( this->_rset, 2, _faces, true );MB_CHK_ERR( error ); 00217 error = mb->get_entities_by_dimension( this->_rset, 3, _cells, true );MB_CHK_ERR( error ); 00218 } 00219 #else 00220 error = mb->get_entities_by_dimension( this->_rset, 0, _verts, true );MB_CHK_ERR( error ); 00221 error = mb->get_entities_by_dimension( this->_rset, 1, _edges, true );MB_CHK_ERR( error ); 00222 error = mb->get_entities_by_dimension( this->_rset, 2, _faces, true );MB_CHK_ERR( error ); 00223 error = mb->get_entities_by_dimension( this->_rset, 3, _cells, true );MB_CHK_ERR( error ); 00224 00225 #endif 00226 00227 int nverts = _verts.size(); 00228 int nedges = _edges.size(); 00229 int nfaces = _faces.size(); 00230 int ncells = _cells.size(); 00231 00232 MESHTYPE mesh_type = get_mesh_type( nverts, nedges, nfaces, ncells ); 00233 thismeshtype = mesh_type; 00234 00235 // Initialize mesh type specific maps 00236 if( thismeshtype == CURVE ) 00237 { 00238 error = init_curve();MB_CHK_ERR( error ); 00239 } 00240 else if( thismeshtype == SURFACE ) 00241 { 00242 error = init_surface();MB_CHK_ERR( error ); 00243 } 00244 else if( thismeshtype == SURFACE_MIXED ) 00245 { 00246 error = init_curve();MB_CHK_ERR( error ); 00247 error = init_surface();MB_CHK_ERR( error ); 00248 } 00249 else if( thismeshtype == VOLUME ) 00250 { 00251 error = init_volume();MB_CHK_ERR( error ); 00252 } 00253 else if( thismeshtype == VOLUME_MIXED_1 ) 00254 { 00255 error = init_curve();MB_CHK_ERR( error ); 00256 error = init_volume();MB_CHK_ERR( error ); 00257 } 00258 else if( thismeshtype == VOLUME_MIXED_2 ) 00259 { 00260 error = init_surface();MB_CHK_ERR( error ); 00261 error = init_volume();MB_CHK_ERR( error ); 00262 } 00263 else if( thismeshtype == VOLUME_MIXED ) 00264 { 00265 error = init_curve();MB_CHK_ERR( error ); 00266 error = init_surface();MB_CHK_ERR( error ); 00267 error = init_volume();MB_CHK_ERR( error ); 00268 } 00269 } 00270 return MB_SUCCESS; 00271 } 00272 00273 ErrorCode HalfFacetRep::deinitialize() 00274 { 00275 return MB_SUCCESS; 00276 } 00277 00278 ErrorCode HalfFacetRep::init_curve() 00279 { 00280 ErrorCode error; 00281 00282 int nv = ID_FROM_HANDLE( *( _verts.end() - 1 ) ); 00283 int ne = ID_FROM_HANDLE( *( _edges.end() - 1 ) ); 00284 00285 v2hv.resize( nv, 0 ); 00286 sibhvs.resize( ne * 2, 0 ); 00287 00288 error = determine_sibling_halfverts( _verts, _edges );MB_CHK_ERR( error ); 00289 error = determine_incident_halfverts( _edges );MB_CHK_ERR( error ); 00290 00291 return MB_SUCCESS; 00292 } 00293 00294 ErrorCode HalfFacetRep::init_surface() 00295 { 00296 ErrorCode error; 00297 EntityType ftype = mb->type_from_handle( *_faces.begin() ); 00298 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 00299 00300 int nv = ID_FROM_HANDLE( *( _verts.end() - 1 ) ); 00301 int nf = ID_FROM_HANDLE( *( _faces.end() - 1 ) ); 00302 00303 v2he.resize( nv, 0 ); 00304 sibhes.resize( nf * nepf, 0 ); 00305 00306 // Construct ahf maps 00307 error = determine_sibling_halfedges( _faces );MB_CHK_ERR( error ); 00308 error = determine_incident_halfedges( _faces );MB_CHK_ERR( error ); 00309 00310 // Initialize queues for storing face and local id's during local search 00311 for( int i = 0; i < MAXSIZE; i++ ) 00312 { 00313 queue_fid[i] = 0; 00314 queue_lid[i] = 0; 00315 trackfaces[i] = 0; 00316 } 00317 00318 return MB_SUCCESS; 00319 } 00320 00321 ErrorCode HalfFacetRep::init_volume() 00322 { 00323 ErrorCode error; 00324 00325 // Initialize std::map between cell-types and their index in lConnMap3D 00326 cell_index[MBTET] = 0; 00327 cell_index[MBPYRAMID] = 1; 00328 cell_index[MBPRISM] = 2; 00329 cell_index[MBHEX] = 3; 00330 00331 int index = get_index_in_lmap( *_cells.begin() ); 00332 int nfpc = lConnMap3D[index].num_faces_in_cell; 00333 int nv = ID_FROM_HANDLE( *( _verts.end() - 1 ) ); 00334 int nc = ID_FROM_HANDLE( *( _cells.end() - 1 ) ); 00335 ; 00336 00337 v2hf.resize( nv, 0 ); 00338 sibhfs.resize( nc * nfpc, 0 ); 00339 00340 // Construct the maps 00341 error = determine_sibling_halffaces( _cells );MB_CHK_ERR( error ); 00342 error = determine_incident_halffaces( _cells );MB_CHK_ERR( error ); 00343 00344 // Initialize queues for storing face and local id's during local search 00345 for( int i = 0; i < MAXSIZE; i++ ) 00346 { 00347 Stkcells[i] = 0; 00348 cellq[i] = 0; 00349 trackcells[i] = 0; 00350 } 00351 00352 return MB_SUCCESS; 00353 } 00354 00355 ////////////////////////////////////////////////// 00356 ErrorCode HalfFacetRep::print_tags( int dim ) 00357 { 00358 if( dim == 1 ) 00359 { 00360 EntityHandle start_edge = *_edges.begin(); 00361 std::cout << "start_edge = " << start_edge << std::endl; 00362 std::cout << "<SIBHVS_EID,SIBHVS_LVID>" << std::endl; 00363 00364 for( Range::iterator i = _edges.begin(); i != _edges.end(); ++i ) 00365 { 00366 EntityHandle eid[2]; 00367 int lvid[2]; 00368 int eidx = ID_FROM_HANDLE( *i ) - 1; 00369 HFacet hf1 = sibhvs[2 * eidx]; 00370 HFacet hf2 = sibhvs[2 * eidx + 1]; 00371 eid[0] = fid_from_halfacet( hf1, MBEDGE ); 00372 eid[1] = fid_from_halfacet( hf2, MBEDGE ); 00373 lvid[0] = lid_from_halffacet( hf1 ); 00374 lvid[1] = lid_from_halffacet( hf2 ); 00375 std::cout << "Entity = " << *i << " :: <" << eid[0] << "," << lvid[0] << ">" 00376 << " " 00377 << "<" << eid[1] << "," << lvid[1] << ">" << std::endl; 00378 } 00379 00380 std::cout << "<V2HV_EID, V2HV_LVID>" << std::endl; 00381 00382 for( Range::iterator i = _verts.begin(); i != _verts.end(); ++i ) 00383 { 00384 int vidx = ID_FROM_HANDLE( *i ) - 1; 00385 HFacet hf = v2hv[vidx]; 00386 EntityHandle eid = fid_from_halfacet( hf, MBEDGE ); 00387 int lvid = lid_from_halffacet( hf ); 00388 std::cout << "Vertex = " << *i << " :: <" << eid << "," << lvid << ">" << std::endl; 00389 } 00390 } 00391 else if( dim == 2 ) 00392 { 00393 EntityType ftype = mb->type_from_handle( *_faces.begin() ); 00394 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 00395 EntityHandle start_face = *_faces.begin(); 00396 std::cout << "start_face = " << start_face << std::endl; 00397 std::cout << "<SIBHES_FID,SIBHES_LEID>" << std::endl; 00398 00399 for( Range::iterator i = _faces.begin(); i != _faces.end(); ++i ) 00400 { 00401 int fidx = ID_FROM_HANDLE( *i ) - 1; 00402 std::cout << "Entity = " << *i; 00403 for( int j = 0; j < nepf; j++ ) 00404 { 00405 HFacet hf = sibhes[nepf * fidx + j]; 00406 EntityHandle sib = fid_from_halfacet( hf, ftype ); 00407 int lid = lid_from_halffacet( hf ); 00408 std::cout << " :: <" << sib << "," << lid << ">" 00409 << " "; 00410 } 00411 std::cout << std::endl; 00412 } 00413 00414 std::cout << "<V2HE_FID, V2HE_LEID>" << std::endl; 00415 00416 for( Range::iterator i = _verts.begin(); i != _verts.end(); ++i ) 00417 { 00418 int vidx = ID_FROM_HANDLE( *i ) - 1; 00419 HFacet hf = v2he[vidx]; 00420 EntityHandle fid = fid_from_halfacet( hf, ftype ); 00421 int lid = lid_from_halffacet( hf ); 00422 std::cout << "Vertex = " << *i << " :: <" << fid << "," << lid << ">" << std::endl; 00423 } 00424 } 00425 else if( dim == 3 ) 00426 { 00427 EntityType ctype = mb->type_from_handle( *_cells.begin() ); 00428 00429 int index = get_index_in_lmap( *_cells.begin() ); 00430 int nfpc = lConnMap3D[index].num_faces_in_cell; 00431 EntityHandle start_cell = *_cells.begin(); 00432 std::cout << "start_cell = " << start_cell << std::endl; 00433 std::cout << "<SIBHES_CID,SIBHES_LFID>" << std::endl; 00434 00435 for( Range::iterator i = _cells.begin(); i != _cells.end(); ++i ) 00436 { 00437 int cidx = ID_FROM_HANDLE( *i ) - 1; 00438 std::cout << "Entity = " << *i; 00439 for( int j = 0; j < nfpc; j++ ) 00440 { 00441 HFacet hf = sibhfs[nfpc * cidx + j]; 00442 EntityHandle sib = fid_from_halfacet( hf, ctype ); 00443 int lid = lid_from_halffacet( hf ); 00444 std::cout << " :: <" << sib << "," << lid << ">" 00445 << " "; 00446 } 00447 std::cout << std::endl; 00448 } 00449 00450 std::cout << "<V2HF_CID, V2HF_LFID>" << std::endl; 00451 EntityHandle cid; 00452 int lid; 00453 00454 for( Range::iterator i = _verts.begin(); i != _verts.end(); ++i ) 00455 { 00456 int vidx = ID_FROM_HANDLE( *i ) - 1; 00457 HFacet hf = v2hf[vidx]; 00458 00459 if( hf == 0 && ( v2hfs.find( *i ) != v2hfs.end() ) ) 00460 { 00461 std::pair< std::multimap< EntityHandle, HFacet >::iterator, 00462 std::multimap< EntityHandle, HFacet >::iterator > 00463 it_hfs; 00464 it_hfs = v2hfs.equal_range( *i ); 00465 00466 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hfs.first; it != it_hfs.second; ++it ) 00467 { 00468 cid = fid_from_halfacet( it->second, ctype ); 00469 lid = lid_from_halffacet( hf ); 00470 00471 std::cout << "Vertex = " << *i << " :: <" << cid << "," << lid << ">" << std::endl; 00472 } 00473 } 00474 else 00475 { 00476 cid = fid_from_halfacet( hf, ctype ); 00477 lid = lid_from_halffacet( hf ); 00478 std::cout << "Vertex = " << *i << " :: <" << cid << "," << lid << ">" << std::endl; 00479 } 00480 } 00481 } 00482 return MB_SUCCESS; 00483 } 00484 00485 /********************************************************** 00486 * User interface for adjacency functions * 00487 ********************************************************/ 00488 00489 ErrorCode HalfFacetRep::get_adjacencies( const EntityHandle source_entity, 00490 const unsigned int target_dimension, 00491 std::vector< EntityHandle >& target_entities ) 00492 { 00493 00494 ErrorCode error; 00495 00496 unsigned int source_dimension = mb->dimension_from_handle( source_entity ); 00497 assert( ( source_dimension <= target_dimension ) || ( source_dimension > target_dimension ) ); 00498 00499 if( mInitAHFmaps == false ) 00500 { 00501 error = initialize();MB_CHK_ERR( error ); 00502 } 00503 00504 int mindex = get_index_for_meshtype( thismeshtype ); 00505 int adj_possible = adjMatrix[mindex].val[source_dimension][target_dimension]; 00506 00507 if( adj_possible ) 00508 { 00509 if( source_dimension < target_dimension ) 00510 { 00511 error = get_up_adjacencies( source_entity, target_dimension, target_entities );MB_CHK_ERR( error ); 00512 } 00513 else if( source_dimension == target_dimension ) 00514 { 00515 error = get_neighbor_adjacencies( source_entity, target_entities );MB_CHK_ERR( error ); 00516 } 00517 else 00518 { 00519 error = get_down_adjacencies( source_entity, target_dimension, target_entities );MB_CHK_ERR( error ); 00520 } 00521 } 00522 else 00523 return MB_SUCCESS; 00524 00525 return MB_SUCCESS; 00526 } 00527 00528 ErrorCode HalfFacetRep::get_up_adjacencies( EntityHandle ent, 00529 int out_dim, 00530 std::vector< EntityHandle >& adjents, 00531 std::vector< int >* lids ) 00532 { 00533 ErrorCode error; 00534 int in_dim = mb->dimension_from_handle( ent ); 00535 assert( ( in_dim >= 0 && in_dim <= 2 ) && ( out_dim > in_dim ) ); 00536 00537 if( in_dim == 0 ) 00538 { 00539 if( out_dim == 1 ) 00540 { 00541 error = get_up_adjacencies_1d( ent, adjents, lids );MB_CHK_ERR( error ); 00542 } 00543 else if( out_dim == 2 ) 00544 { 00545 error = get_up_adjacencies_vert_2d( ent, adjents );MB_CHK_ERR( error ); 00546 } 00547 else if( out_dim == 3 ) 00548 { 00549 error = get_up_adjacencies_vert_3d( ent, adjents );MB_CHK_ERR( error ); 00550 } 00551 } 00552 00553 else if( ( in_dim == 1 ) && ( out_dim == 2 ) ) 00554 { 00555 error = get_up_adjacencies_2d( ent, adjents, lids );MB_CHK_ERR( error ); 00556 } 00557 else if( ( in_dim == 1 ) && ( out_dim == 3 ) ) 00558 { 00559 error = get_up_adjacencies_edg_3d( ent, adjents, lids );MB_CHK_ERR( error ); 00560 } 00561 else if( ( in_dim == 2 ) && ( out_dim == 3 ) ) 00562 { 00563 error = get_up_adjacencies_face_3d( ent, adjents, lids );MB_CHK_ERR( error ); 00564 } 00565 return MB_SUCCESS; 00566 } 00567 00568 ErrorCode HalfFacetRep::get_neighbor_adjacencies( EntityHandle ent, std::vector< EntityHandle >& adjents ) 00569 { 00570 ErrorCode error; 00571 int in_dim = mb->dimension_from_handle( ent ); 00572 assert( in_dim >= 1 && in_dim <= 3 ); 00573 00574 if( in_dim == 1 ) 00575 { 00576 error = get_neighbor_adjacencies_1d( ent, adjents );MB_CHK_ERR( error ); 00577 } 00578 00579 else if( in_dim == 2 ) 00580 { 00581 error = get_neighbor_adjacencies_2d( ent, adjents );MB_CHK_ERR( error ); 00582 } 00583 else if( in_dim == 3 ) 00584 { 00585 error = get_neighbor_adjacencies_3d( ent, adjents );MB_CHK_ERR( error ); 00586 } 00587 return MB_SUCCESS; 00588 } 00589 00590 ErrorCode HalfFacetRep::get_down_adjacencies( EntityHandle ent, int out_dim, std::vector< EntityHandle >& adjents ) 00591 { 00592 ErrorCode error; 00593 int in_dim = mb->dimension_from_handle( ent ); 00594 assert( ( in_dim >= 2 && in_dim <= 3 ) && ( out_dim < in_dim ) ); 00595 00596 if( ( in_dim == 2 ) && ( out_dim == 1 ) ) 00597 { 00598 error = get_down_adjacencies_2d( ent, adjents );MB_CHK_ERR( error ); 00599 } 00600 else if( ( in_dim == 3 ) && ( out_dim == 1 ) ) 00601 { 00602 error = get_down_adjacencies_edg_3d( ent, adjents );MB_CHK_ERR( error ); 00603 } 00604 else if( ( in_dim == 3 ) && ( out_dim == 2 ) ) 00605 { 00606 error = get_down_adjacencies_face_3d( ent, adjents );MB_CHK_ERR( error ); 00607 } 00608 return MB_SUCCESS; 00609 } 00610 00611 ErrorCode HalfFacetRep::count_subentities( Range& edges, Range& faces, Range& cells, int* nedges, int* nfaces ) 00612 { 00613 ErrorCode error; 00614 if( edges.size() && !faces.size() && !cells.size() ) 00615 { 00616 nedges[0] = edges.size(); 00617 nfaces[0] = 0; 00618 } 00619 else if( faces.size() && !cells.size() ) 00620 { 00621 nedges[0] = find_total_edges_2d( faces ); 00622 nfaces[0] = 0; 00623 } 00624 else if( cells.size() ) 00625 { 00626 error = find_total_edges_faces_3d( cells, nedges, nfaces );MB_CHK_ERR( error ); 00627 } 00628 return MB_SUCCESS; 00629 } 00630 00631 /******************************************************** 00632 * 1D: sibhvs, v2hv, incident and neighborhood queries * 00633 *********************************************************/ 00634 ErrorCode HalfFacetRep::determine_sibling_halfverts( Range& verts, Range& edges ) 00635 { 00636 ErrorCode error; 00637 00638 // Step 1: Create an index list storing the starting position for each vertex 00639 int nv = verts.size(); 00640 std::vector< int > is_index( nv + 1 ); 00641 for( int i = 0; i < nv + 1; i++ ) 00642 is_index[i] = 0; 00643 00644 for( Range::iterator eid = edges.begin(); eid != edges.end(); ++eid ) 00645 { 00646 const EntityHandle* conn; 00647 int num_conn = 0; 00648 error = mb->get_connectivity( *eid, conn, num_conn, true );MB_CHK_ERR( error ); 00649 00650 int index = verts.index( conn[0] ); 00651 is_index[index + 1] += 1; 00652 index = verts.index( conn[1] ); 00653 is_index[index + 1] += 1; 00654 } 00655 is_index[0] = 0; 00656 00657 for( int i = 0; i < nv; i++ ) 00658 is_index[i + 1] = is_index[i] + is_index[i + 1]; 00659 00660 // Step 2: Define two arrays v2hv_eid, v2hv_lvid storing every half-facet on a vertex 00661 std::vector< EntityHandle > v2hv_map_eid( 2 * edges.size() ); 00662 std::vector< int > v2hv_map_lvid( 2 * edges.size() ); 00663 00664 for( Range::iterator eid = edges.begin(); eid != edges.end(); ++eid ) 00665 { 00666 const EntityHandle* conn; 00667 int num_conn = 0; 00668 error = mb->get_connectivity( *eid, conn, num_conn, true );MB_CHK_ERR( error ); 00669 00670 for( int j = 0; j < 2; j++ ) 00671 { 00672 int v = verts.index( conn[j] ); 00673 v2hv_map_eid[is_index[v]] = *eid; 00674 v2hv_map_lvid[is_index[v]] = j; 00675 is_index[v] += 1; 00676 } 00677 } 00678 00679 for( int i = nv - 2; i >= 0; i-- ) 00680 is_index[i + 1] = is_index[i]; 00681 is_index[0] = 0; 00682 00683 // Step 3: Fill up sibling half-verts map 00684 for( Range::iterator vid = verts.begin(); vid != verts.end(); ++vid ) 00685 { 00686 int v = verts.index( *vid ); 00687 int last = is_index[v + 1] - 1; 00688 if( last > is_index[v] ) 00689 { 00690 EntityHandle prev_eid = v2hv_map_eid[last]; 00691 int prev_lvid = v2hv_map_lvid[last]; 00692 00693 for( int i = is_index[v]; i <= last; i++ ) 00694 { 00695 EntityHandle cur_eid = v2hv_map_eid[i]; 00696 int cur_lvid = v2hv_map_lvid[i]; 00697 00698 int pidx = ID_FROM_HANDLE( prev_eid ) - 1; 00699 sibhvs[2 * pidx + prev_lvid] = create_halffacet( cur_eid, cur_lvid ); 00700 00701 prev_eid = cur_eid; 00702 prev_lvid = cur_lvid; 00703 } 00704 } 00705 } 00706 00707 return MB_SUCCESS; 00708 } 00709 00710 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00711 ErrorCode HalfFacetRep::determine_incident_halfverts( Range& edges ) 00712 { 00713 ErrorCode error; 00714 00715 for( Range::iterator e_it = edges.begin(); e_it != edges.end(); ++e_it ) 00716 { 00717 EntityHandle cur_eid = *e_it; 00718 const EntityHandle* conn; 00719 int num_conn = 0; 00720 error = mb->get_connectivity( *e_it, conn, num_conn, true );MB_CHK_ERR( error ); 00721 00722 for( int i = 0; i < 2; ++i ) 00723 { 00724 EntityHandle v = conn[i]; 00725 int vidx = ID_FROM_HANDLE( v ) - 1; 00726 00727 HFacet hf = v2hv[vidx]; 00728 EntityHandle eid = fid_from_halfacet( hf, MBEDGE ); 00729 if( eid == 0 ) 00730 { 00731 v2hv[vidx] = create_halffacet( cur_eid, i ); 00732 } 00733 } 00734 } 00735 00736 return MB_SUCCESS; 00737 } 00738 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00739 ErrorCode HalfFacetRep::get_up_adjacencies_1d( EntityHandle vid, 00740 std::vector< EntityHandle >& adjents, 00741 std::vector< int >* lvids ) 00742 { 00743 adjents.clear(); 00744 adjents.reserve( 20 ); 00745 00746 if( lvids != NULL ) lvids->reserve( 20 ); 00747 00748 int vidx = ID_FROM_HANDLE( vid ) - 1; 00749 HFacet hf = v2hv[vidx]; 00750 00751 EntityHandle start_eid = fid_from_halfacet( hf, MBEDGE ); 00752 int start_lid = lid_from_halffacet( hf ); 00753 00754 EntityHandle eid = start_eid; 00755 int lid = start_lid; 00756 00757 if( eid != 0 ) 00758 { 00759 adjents.push_back( eid ); 00760 if( lvids != NULL ) lvids->push_back( lid ); 00761 00762 while( eid != 0 ) 00763 { 00764 int eidx = ID_FROM_HANDLE( eid ) - 1; 00765 HFacet shf = sibhvs[2 * eidx + lid]; 00766 eid = fid_from_halfacet( shf, MBEDGE ); 00767 lid = lid_from_halffacet( shf ); 00768 00769 if( ( !eid ) || ( eid == start_eid ) ) break; 00770 00771 adjents.push_back( eid ); 00772 if( lvids != NULL ) lvids->push_back( lid ); 00773 } 00774 } 00775 00776 return MB_SUCCESS; 00777 } 00778 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00779 ErrorCode HalfFacetRep::get_neighbor_adjacencies_1d( EntityHandle eid, std::vector< EntityHandle >& adjents ) 00780 { 00781 adjents.clear(); 00782 adjents.reserve( 20 ); 00783 00784 EntityHandle sibhv_eid; 00785 int sibhv_lid; 00786 int eidx = ID_FROM_HANDLE( eid ) - 1; 00787 00788 for( int lid = 0; lid < 2; ++lid ) 00789 { 00790 HFacet shf = sibhvs[2 * eidx + lid]; 00791 sibhv_eid = fid_from_halfacet( shf, MBEDGE ); 00792 sibhv_lid = lid_from_halffacet( shf ); 00793 00794 if( sibhv_eid != 0 ) 00795 { 00796 adjents.push_back( sibhv_eid ); 00797 00798 eidx = ID_FROM_HANDLE( sibhv_eid ) - 1; 00799 HFacet nhf = sibhvs[2 * eidx + sibhv_lid]; 00800 EntityHandle hv_eid = fid_from_halfacet( nhf, MBEDGE ); 00801 int hv_lid = lid_from_halffacet( nhf ); 00802 00803 while( hv_eid != 0 ) 00804 { 00805 if( hv_eid != eid ) adjents.push_back( hv_eid ); 00806 00807 eidx = ID_FROM_HANDLE( hv_eid ) - 1; 00808 HFacet hf = sibhvs[2 * eidx + hv_lid]; 00809 EntityHandle edge = fid_from_halfacet( hf, MBEDGE ); 00810 if( edge == sibhv_eid ) break; 00811 00812 hv_eid = edge; 00813 hv_lid = lid_from_halffacet( hf ); 00814 } 00815 } 00816 } 00817 00818 return MB_SUCCESS; 00819 } 00820 00821 /******************************************************* 00822 * 2D: sibhes, v2he, incident and neighborhood queries * 00823 ********************************************************/ 00824 const HalfFacetRep::LocalMaps2D HalfFacetRep::lConnMap2D[2] = { 00825 // Triangle 00826 { 3, { 1, 2, 0 }, { 2, 0, 1 } }, 00827 // Quad 00828 { 4, { 1, 2, 3, 0 }, { 3, 0, 1, 2 } } }; 00829 00830 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00831 ErrorCode HalfFacetRep::determine_sibling_halfedges( Range& faces ) 00832 { 00833 ErrorCode error; 00834 EntityHandle start_face = *faces.begin(); 00835 EntityType ftype = mb->type_from_handle( start_face ); 00836 int nfaces = faces.size(); 00837 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 00838 00839 // Step 1: Create an index list storing the starting position for each vertex 00840 int nv = _verts.size(); 00841 std::vector< int > is_index( nv + 1 ); 00842 for( int i = 0; i < nv + 1; i++ ) 00843 is_index[i] = 0; 00844 00845 int index; 00846 00847 for( Range::iterator fid = faces.begin(); fid != faces.end(); ++fid ) 00848 { 00849 const EntityHandle* conn; 00850 error = mb->get_connectivity( *fid, conn, nepf, true );MB_CHK_ERR( error ); 00851 00852 for( int i = 0; i < nepf; i++ ) 00853 { 00854 index = _verts.index( conn[i] ); 00855 is_index[index + 1] += 1; 00856 } 00857 } 00858 is_index[0] = 0; 00859 00860 for( int i = 0; i < nv; i++ ) 00861 is_index[i + 1] = is_index[i] + is_index[i + 1]; 00862 00863 // Step 2: Define two arrays v2hv_eid, v2hv_lvid storing every half-facet on a vertex 00864 std::vector< EntityHandle > v2nv( nepf * nfaces ); 00865 std::vector< EntityHandle > v2he_map_fid( nepf * nfaces ); 00866 std::vector< int > v2he_map_leid( nepf * nfaces ); 00867 00868 for( Range::iterator fid = faces.begin(); fid != faces.end(); ++fid ) 00869 { 00870 const EntityHandle* conn; 00871 error = mb->get_connectivity( *fid, conn, nepf, true );MB_CHK_ERR( error ); 00872 00873 for( int j = 0; j < nepf; j++ ) 00874 { 00875 int v = _verts.index( conn[j] ); 00876 int nidx = lConnMap2D[ftype - 2].next[j]; 00877 v2nv[is_index[v]] = conn[nidx]; 00878 v2he_map_fid[is_index[v]] = *fid; 00879 v2he_map_leid[is_index[v]] = j; 00880 is_index[v] += 1; 00881 } 00882 } 00883 00884 for( int i = nv - 2; i >= 0; i-- ) 00885 is_index[i + 1] = is_index[i]; 00886 is_index[0] = 0; 00887 00888 // Step 3: Fill up sibling half-verts map 00889 for( Range::iterator fid = faces.begin(); fid != faces.end(); ++fid ) 00890 { 00891 const EntityHandle* conn; 00892 error = mb->get_connectivity( *fid, conn, nepf, true );MB_CHK_ERR( error ); 00893 00894 int fidx = ID_FROM_HANDLE( *fid ) - 1; 00895 for( int k = 0; k < nepf; k++ ) 00896 { 00897 HFacet hf = sibhes[nepf * fidx + k]; 00898 EntityHandle sibfid = fid_from_halfacet( hf, ftype ); 00899 00900 if( sibfid != 0 ) continue; 00901 00902 int nidx = lConnMap2D[ftype - 2].next[k]; 00903 int v = _verts.index( conn[k] ); 00904 int vn = _verts.index( conn[nidx] ); 00905 00906 EntityHandle first_fid = *fid; 00907 int first_leid = k; 00908 00909 EntityHandle prev_fid = *fid; 00910 int prev_leid = k; 00911 00912 for( index = is_index[vn]; index <= is_index[vn + 1] - 1; index++ ) 00913 { 00914 if( v2nv[index] == conn[k] ) 00915 { 00916 EntityHandle cur_fid = v2he_map_fid[index]; 00917 int cur_leid = v2he_map_leid[index]; 00918 00919 int pidx = ID_FROM_HANDLE( prev_fid ) - 1; 00920 sibhes[nepf * pidx + prev_leid] = create_halffacet( cur_fid, cur_leid ); 00921 00922 prev_fid = cur_fid; 00923 prev_leid = cur_leid; 00924 } 00925 } 00926 00927 for( index = is_index[v]; index <= is_index[v + 1] - 1; index++ ) 00928 { 00929 if( ( v2nv[index] == conn[nidx] ) && ( v2he_map_fid[index] != *fid ) ) 00930 { 00931 00932 EntityHandle cur_fid = v2he_map_fid[index]; 00933 int cur_leid = v2he_map_leid[index]; 00934 00935 int pidx = ID_FROM_HANDLE( prev_fid ) - 1; 00936 sibhes[nepf * pidx + prev_leid] = create_halffacet( cur_fid, cur_leid ); 00937 00938 prev_fid = cur_fid; 00939 prev_leid = cur_leid; 00940 } 00941 } 00942 00943 if( prev_fid != first_fid ) 00944 { 00945 00946 int pidx = ID_FROM_HANDLE( prev_fid ) - 1; 00947 sibhes[nepf * pidx + prev_leid] = create_halffacet( first_fid, first_leid ); 00948 } 00949 } 00950 } 00951 00952 return MB_SUCCESS; 00953 } 00954 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00955 ErrorCode HalfFacetRep::determine_incident_halfedges( Range& faces ) 00956 { 00957 ErrorCode error; 00958 EntityType ftype = mb->type_from_handle( *faces.begin() ); 00959 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 00960 00961 std::vector< char > markEdges( nepf * faces.size(), 0 ); 00962 00963 for( Range::iterator it = faces.begin(); it != faces.end(); ++it ) 00964 { 00965 EntityHandle fid = *it; 00966 const EntityHandle* conn; 00967 error = mb->get_connectivity( fid, conn, nepf, true );MB_CHK_ERR( error ); 00968 00969 for( int i = 0; i < nepf; ++i ) 00970 { 00971 EntityHandle v = conn[i]; 00972 int vidx = ID_FROM_HANDLE( v ) - 1; 00973 HFacet hf = v2he[vidx]; 00974 00975 if( hf == 0 && ( v2hes.empty() || ( v2hes.find( v ) == v2hes.end() ) ) ) 00976 { 00977 // This is the first time a half-facet is assigned to a vertex. 00978 HFacet nwhf = 0; 00979 error = mark_halfedges( v, fid, i, faces, markEdges, nwhf );MB_CHK_ERR( error ); 00980 00981 if( nwhf == 0 ) nwhf = create_halffacet( fid, i ); 00982 00983 v2he[vidx] = nwhf; 00984 } 00985 else if( hf != 0 && !markEdges[nepf * faces.index( fid ) + i] ) 00986 { 00987 // This is the first time a non-manifold vertex is encountered. Copy the existing he 00988 // in v2he[v] to the multimap. 00989 v2hes.insert( std::pair< EntityHandle, HFacet >( v, hf ) ); 00990 HFacet nwhf = 0; 00991 error = mark_halfedges( v, fid, i, faces, markEdges, nwhf );MB_CHK_ERR( error ); 00992 00993 if( nwhf == 0 ) nwhf = create_halffacet( fid, i ); 00994 00995 v2hes.insert( std::pair< EntityHandle, HFacet >( v, nwhf ) ); 00996 v2he[vidx] = 0; 00997 } 00998 else if( hf == 0 && ( !v2hes.empty() ) && ( v2hes.find( v ) != v2hes.end() ) && 00999 !markEdges[nepf * faces.index( fid ) + i] ) 01000 { 01001 // This is check if reached if the vertex is non-manifold and has encountered a 01002 // half-facet to a new component. 01003 HFacet nwhf = 0; 01004 error = mark_halfedges( v, fid, i, faces, markEdges, nwhf );MB_CHK_ERR( error ); 01005 01006 if( nwhf == 0 ) nwhf = create_halffacet( fid, i ); 01007 01008 v2hes.insert( std::pair< EntityHandle, HFacet >( v, nwhf ) ); 01009 } 01010 } 01011 } 01012 01013 // error = print_tags(2); 01014 01015 return MB_SUCCESS; 01016 } 01017 01018 /////////////////////////////////////////////////////////////////// 01019 ErrorCode HalfFacetRep::mark_halfedges( EntityHandle vid, 01020 EntityHandle he_fid, 01021 int he_lid, 01022 Range& faces, 01023 std::vector< char >& markHEdgs, 01024 HFacet& bnd_hf ) 01025 { 01026 ErrorCode error; 01027 EntityType ftype = mb->type_from_handle( he_fid ); 01028 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 01029 01030 int qsize = 0, count = -1; 01031 int num_qvals = 0; 01032 01033 error = gather_halfedges( vid, he_fid, he_lid, &qsize, &count );MB_CHK_ERR( error ); 01034 01035 while( num_qvals < qsize ) 01036 { 01037 EntityHandle curfid = queue_fid[num_qvals]; 01038 int curlid = queue_lid[num_qvals]; 01039 num_qvals += 1; 01040 01041 int fidx = ID_FROM_HANDLE( curfid ) - 1; 01042 01043 const EntityHandle* conn; 01044 error = mb->get_connectivity( curfid, conn, nepf, true );MB_CHK_ERR( error ); 01045 01046 if( !markHEdgs[nepf * faces.index( curfid ) + curlid] && ( conn[curlid] == vid ) ) 01047 { 01048 markHEdgs[nepf * faces.index( curfid ) + curlid] = 1; 01049 HFacet hf = sibhes[nepf * fidx + curlid]; 01050 EntityHandle sibfid = fid_from_halfacet( hf, ftype ); 01051 if( sibfid == 0 ) bnd_hf = create_halffacet( curfid, curlid ); 01052 } 01053 01054 EntityHandle he2_fid = 0; 01055 int he2_lid = 0; 01056 error = another_halfedge( vid, curfid, curlid, &he2_fid, &he2_lid );MB_CHK_ERR( error ); 01057 01058 if( !markHEdgs[nepf * faces.index( curfid ) + he2_lid] && ( conn[he2_lid] == vid ) ) 01059 { 01060 markHEdgs[nepf * faces.index( curfid ) + he2_lid] = 1; 01061 HFacet hf = sibhes[nepf * fidx + he2_lid]; 01062 EntityHandle sibfid = fid_from_halfacet( hf, ftype ); 01063 if( sibfid == 0 ) bnd_hf = create_halffacet( he2_fid, he2_lid ); 01064 } 01065 01066 bool val = find_match_in_array( he2_fid, trackfaces, count ); 01067 01068 if( val ) continue; 01069 01070 count += 1; 01071 trackfaces[count] = he2_fid; 01072 01073 error = get_up_adjacencies_2d( he2_fid, he2_lid, &qsize, &count );MB_CHK_ERR( error ); 01074 } 01075 01076 // Change the visited faces to false, also empty the queue 01077 for( int i = 0; i <= qsize; i++ ) 01078 { 01079 queue_fid[i] = 0; 01080 queue_lid[i] = 0; 01081 } 01082 01083 for( int i = 0; i <= count; i++ ) 01084 trackfaces[i] = 0; 01085 return MB_SUCCESS; 01086 } 01087 01088 /////////////////////////////////////////////////////////////////// 01089 ErrorCode HalfFacetRep::get_up_adjacencies_vert_2d( EntityHandle vid, std::vector< EntityHandle >& adjents ) 01090 { 01091 ErrorCode error; 01092 EntityType ftype = mb->type_from_handle( *_faces.begin() ); 01093 01094 int vidx = ID_FROM_HANDLE( vid ) - 1; 01095 HFacet hf = v2he[vidx]; 01096 01097 std::vector< EntityHandle > start_fids; 01098 std::vector< int > start_lids; 01099 01100 if( hf == 0 && ( v2hes.find( vid ) != v2hes.end() ) ) 01101 { 01102 std::pair< std::multimap< EntityHandle, HFacet >::iterator, std::multimap< EntityHandle, HFacet >::iterator > 01103 it_hes; 01104 it_hes = v2hes.equal_range( vid ); 01105 01106 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 01107 { 01108 start_fids.push_back( fid_from_halfacet( it->second, ftype ) ); 01109 start_lids.push_back( lid_from_halffacet( it->second ) ); 01110 } 01111 } 01112 else if( hf != 0 ) 01113 { 01114 start_fids.push_back( fid_from_halfacet( hf, ftype ) ); 01115 start_lids.push_back( lid_from_halffacet( hf ) ); 01116 } 01117 01118 if( start_fids.empty() ) return MB_SUCCESS; 01119 01120 int qsize = 0, count = -1; 01121 int num_qvals = 0; 01122 01123 adjents.reserve( (int)start_fids.size() ); 01124 01125 for( int i = 0; i < (int)start_fids.size(); i++ ) 01126 { 01127 adjents.push_back( start_fids[i] ); 01128 error = gather_halfedges( vid, start_fids[i], start_lids[i], &qsize, &count );MB_CHK_ERR( error ); 01129 } 01130 01131 while( num_qvals < qsize ) 01132 { 01133 EntityHandle curfid = queue_fid[num_qvals]; 01134 int curlid = queue_lid[num_qvals]; 01135 num_qvals += 1; 01136 01137 EntityHandle he2_fid = 0; 01138 int he2_lid = 0; 01139 error = another_halfedge( vid, curfid, curlid, &he2_fid, &he2_lid );MB_CHK_ERR( error ); 01140 01141 bool val = find_match_in_array( he2_fid, trackfaces, count ); 01142 01143 if( val ) continue; 01144 01145 count += 1; 01146 trackfaces[count] = he2_fid; 01147 01148 error = get_up_adjacencies_2d( he2_fid, he2_lid, &qsize, &count );MB_CHK_ERR( error ); 01149 01150 adjents.push_back( he2_fid ); 01151 } 01152 01153 // Change the visited faces to false, also empty the queue 01154 for( int i = 0; i <= qsize; i++ ) 01155 { 01156 queue_fid[i] = 0; 01157 queue_lid[i] = 0; 01158 } 01159 01160 for( int i = 0; i <= count; i++ ) 01161 trackfaces[i] = 0; 01162 01163 return MB_SUCCESS; 01164 } 01165 01166 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 01167 ErrorCode HalfFacetRep::get_up_adjacencies_2d( EntityHandle eid, 01168 std::vector< EntityHandle >& adjents, 01169 std::vector< int >* leids ) 01170 { 01171 01172 // Given an explicit edge eid, find the incident faces. 01173 ErrorCode error; 01174 EntityHandle he_fid = 0; 01175 int he_lid = 0; 01176 01177 // Step 1: Given an explicit edge, find a corresponding half-edge from the surface mesh. 01178 bool found = find_matching_halfedge( eid, &he_fid, &he_lid ); 01179 01180 // Step 2: If there is a corresponding half-edge, collect all sibling half-edges and store the 01181 // incident faces. 01182 if( found ) 01183 { 01184 error = get_up_adjacencies_2d( he_fid, he_lid, true, adjents, leids );MB_CHK_ERR( error ); 01185 } 01186 01187 return MB_SUCCESS; 01188 } 01189 01190 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 01191 ErrorCode HalfFacetRep::get_up_adjacencies_2d( EntityHandle fid, 01192 int leid, 01193 bool add_inent, 01194 std::vector< EntityHandle >& adj_ents, 01195 std::vector< int >* adj_leids, 01196 std::vector< int >* adj_orients ) 01197 { 01198 // Given an implicit half-edge <fid, leid>, find the incident half-edges. 01199 ErrorCode error; 01200 01201 EntityType ftype = mb->type_from_handle( fid ); 01202 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 01203 01204 if( !fid ) return MB_FAILURE; 01205 adj_ents.reserve( 20 ); 01206 01207 bool local_id = false; 01208 bool orient = false; 01209 if( adj_leids != NULL ) 01210 { 01211 local_id = true; 01212 adj_leids->reserve( 20 ); 01213 } 01214 if( adj_orients != NULL ) 01215 { 01216 orient = true; 01217 adj_orients->reserve( 20 ); 01218 } 01219 01220 if( add_inent ) 01221 { 01222 adj_ents.push_back( fid ); 01223 if( local_id ) adj_leids->push_back( leid ); 01224 } 01225 01226 EntityHandle fedge[2] = { 0, 0 }; 01227 01228 if( orient ) 01229 { 01230 // get connectivity and match their directions 01231 const EntityHandle* fid_conn; 01232 error = mb->get_connectivity( fid, fid_conn, nepf, true );MB_CHK_ERR( error ); 01233 01234 int nidx = lConnMap2D[ftype - 2].next[leid]; 01235 fedge[0] = fid_conn[leid]; 01236 fedge[1] = fid_conn[nidx]; 01237 } 01238 01239 int fidx = ID_FROM_HANDLE( fid ) - 1; 01240 HFacet hf = sibhes[nepf * fidx + leid]; 01241 EntityHandle curfid = fid_from_halfacet( hf, ftype ); 01242 int curlid = lid_from_halffacet( hf ); 01243 01244 while( ( curfid != fid ) && ( curfid != 0 ) ) 01245 { // Should not go into the loop when no sibling exists 01246 adj_ents.push_back( curfid ); 01247 01248 if( local_id ) adj_leids->push_back( curlid ); 01249 01250 if( orient ) 01251 { 01252 // get connectivity and match their directions 01253 const EntityHandle* conn; 01254 error = mb->get_connectivity( curfid, conn, nepf, true );MB_CHK_ERR( error ); 01255 01256 int nidx = lConnMap2D[ftype - 2].next[curlid]; 01257 01258 if( ( fedge[0] == conn[curlid] ) && ( fedge[1] == conn[nidx] ) ) 01259 adj_orients->push_back( 1 ); 01260 else if( ( fedge[1] == conn[curlid] ) && ( fedge[0] == conn[nidx] ) ) 01261 adj_orients->push_back( 0 ); 01262 } 01263 01264 int cidx = ID_FROM_HANDLE( curfid ) - 1; 01265 hf = sibhes[nepf * cidx + curlid]; 01266 curfid = fid_from_halfacet( hf, ftype ); 01267 curlid = lid_from_halffacet( hf ); 01268 } 01269 01270 return MB_SUCCESS; 01271 } 01272 01273 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 01274 ErrorCode HalfFacetRep::get_up_adjacencies_2d( EntityHandle fid, int lid, int* qsize, int* count ) 01275 { 01276 EntityType ftype = mb->type_from_handle( fid ); 01277 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 01278 01279 int fidx = ID_FROM_HANDLE( fid ) - 1; 01280 HFacet hf = sibhes[nepf * fidx + lid]; 01281 EntityHandle curfid = fid_from_halfacet( hf, ftype ); 01282 int curlid = lid_from_halffacet( hf ); 01283 01284 if( curfid == 0 ) 01285 { 01286 int index = 0; 01287 bool found_ent = find_match_in_array( fid, queue_fid, qsize[0] - 1, true, &index ); 01288 01289 if( ( !found_ent ) || ( ( found_ent ) && ( queue_lid[index] != lid ) ) ) 01290 { 01291 queue_fid[qsize[0]] = fid; 01292 queue_lid[qsize[0]] = lid; 01293 qsize[0] += 1; 01294 } 01295 } 01296 01297 while( ( curfid != fid ) && ( curfid != 0 ) ) 01298 { 01299 bool val = find_match_in_array( curfid, trackfaces, count[0] ); 01300 01301 if( !val ) 01302 { 01303 queue_fid[qsize[0]] = curfid; 01304 queue_lid[qsize[0]] = curlid; 01305 qsize[0] += 1; 01306 } 01307 01308 int cidx = ID_FROM_HANDLE( curfid ) - 1; 01309 hf = sibhes[nepf * cidx + curlid]; 01310 curfid = fid_from_halfacet( hf, ftype ); 01311 curlid = lid_from_halffacet( hf ); 01312 } 01313 01314 return MB_SUCCESS; 01315 } 01316 01317 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 01318 bool HalfFacetRep::find_matching_halfedge( EntityHandle eid, EntityHandle* hefid, int* helid ) 01319 { 01320 ErrorCode error; 01321 EntityType ftype = mb->type_from_handle( *_faces.begin() ); 01322 01323 const EntityHandle* conn; 01324 int num_conn = 0; 01325 error = mb->get_connectivity( eid, conn, num_conn, true );MB_CHK_ERR( error ); 01326 01327 EntityHandle vid = conn[0]; 01328 int vidx = ID_FROM_HANDLE( conn[0] ) - 1; 01329 HFacet hf = v2he[vidx]; 01330 01331 if( hf == 0 ) 01332 { 01333 vidx = ID_FROM_HANDLE( conn[1] ) - 1; 01334 hf = v2he[vidx]; 01335 01336 if( hf == 0 ) // The edge is either a dangling edge or attached to two non-manifold 01337 // vertices 01338 return MB_SUCCESS; 01339 01340 vid = conn[1]; 01341 } 01342 01343 EntityHandle fid = fid_from_halfacet( hf, ftype ); 01344 int lid = lid_from_halffacet( hf ); 01345 01346 bool found = false; 01347 int qsize = 0, count = -1; 01348 01349 error = gather_halfedges( vid, fid, lid, &qsize, &count );MB_CHK_ERR( error ); 01350 01351 found = collect_and_compare( vid, conn, &qsize, &count, hefid, helid );MB_CHK_ERR( error ); 01352 01353 // Change the visited faces to false 01354 for( int i = 0; i < qsize; i++ ) 01355 { 01356 queue_fid[i] = 0; 01357 queue_lid[i] = 0; 01358 } 01359 01360 for( int i = 0; i <= count; i++ ) 01361 trackfaces[i] = 0; 01362 01363 return found; 01364 } 01365 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 01366 ErrorCode HalfFacetRep::gather_halfedges( EntityHandle vid, EntityHandle he_fid, int he_lid, int* qsize, int* count ) 01367 { 01368 ErrorCode error; 01369 EntityHandle he2_fid = 0; 01370 int he2_lid = 0; 01371 01372 error = another_halfedge( vid, he_fid, he_lid, &he2_fid, &he2_lid );MB_CHK_ERR( error ); 01373 01374 queue_fid[*qsize] = he_fid; 01375 queue_lid[*qsize] = he_lid; 01376 *qsize += 1; 01377 01378 queue_fid[*qsize] = he2_fid; 01379 queue_lid[*qsize] = he2_lid; 01380 *qsize += 1; 01381 01382 *count += 1; 01383 trackfaces[*count] = he_fid; 01384 01385 error = get_up_adjacencies_2d( he_fid, he_lid, qsize, count );MB_CHK_ERR( error ); 01386 error = get_up_adjacencies_2d( he2_fid, he2_lid, qsize, count );MB_CHK_ERR( error ); 01387 01388 return MB_SUCCESS; 01389 } 01390 01391 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 01392 ErrorCode HalfFacetRep::another_halfedge( EntityHandle vid, 01393 EntityHandle he_fid, 01394 int he_lid, 01395 EntityHandle* he2_fid, 01396 int* he2_lid ) 01397 { 01398 ErrorCode error; 01399 EntityType ftype = mb->type_from_handle( he_fid ); 01400 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 01401 01402 const EntityHandle* conn; 01403 error = mb->get_connectivity( he_fid, conn, nepf, true );MB_CHK_ERR( error ); 01404 01405 *he2_fid = he_fid; 01406 if( conn[he_lid] == vid ) 01407 *he2_lid = lConnMap2D[ftype - 2].prev[he_lid]; 01408 else 01409 *he2_lid = lConnMap2D[ftype - 2].next[he_lid]; 01410 01411 return MB_SUCCESS; 01412 } 01413 01414 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 01415 bool HalfFacetRep::collect_and_compare( const EntityHandle vid, 01416 const EntityHandle* edg_vert, 01417 int* qsize, 01418 int* count, 01419 EntityHandle* he_fid, 01420 int* he_lid ) 01421 { 01422 ErrorCode error; 01423 EntityType ftype = mb->type_from_handle( *_faces.begin() ); 01424 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 01425 01426 bool found = false; 01427 int num_qvals = 0, counter = 0; 01428 01429 while( num_qvals < *qsize && counter < MAXSIZE ) 01430 { 01431 EntityHandle curfid = queue_fid[num_qvals]; 01432 int curlid = queue_lid[num_qvals]; 01433 num_qvals += 1; 01434 01435 const EntityHandle* conn; 01436 error = mb->get_connectivity( curfid, conn, nepf, true );MB_CHK_ERR( error ); 01437 01438 int id = lConnMap2D[ftype - 2].next[curlid]; 01439 if( ( ( conn[curlid] == edg_vert[0] ) && ( conn[id] == edg_vert[1] ) ) || 01440 ( ( conn[curlid] == edg_vert[1] ) && ( conn[id] == edg_vert[0] ) ) ) 01441 { 01442 *he_fid = curfid; 01443 *he_lid = curlid; 01444 found = true; 01445 break; 01446 } 01447 01448 bool val = find_match_in_array( curfid, trackfaces, count[0] ); 01449 01450 if( val ) continue; 01451 01452 count[0] += 1; 01453 trackfaces[*count] = curfid; 01454 01455 EntityHandle he2_fid; 01456 int he2_lid; 01457 error = another_halfedge( vid, curfid, curlid, &he2_fid, &he2_lid );MB_CHK_ERR( error ); 01458 error = get_up_adjacencies_2d( he2_fid, he2_lid, qsize, count );MB_CHK_ERR( error ); 01459 01460 counter += 1; 01461 } 01462 return found; 01463 } 01464 01465 /////////////////////////////////////////////////////////////////////////////////////////////////// 01466 ErrorCode HalfFacetRep::get_neighbor_adjacencies_2d( EntityHandle fid, std::vector< EntityHandle >& adjents ) 01467 { 01468 ErrorCode error; 01469 01470 if( fid != 0 ) 01471 { 01472 EntityType ftype = mb->type_from_handle( fid ); 01473 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 01474 01475 for( int lid = 0; lid < nepf; ++lid ) 01476 { 01477 error = get_up_adjacencies_2d( fid, lid, false, adjents );MB_CHK_ERR( error ); 01478 } 01479 } 01480 01481 return MB_SUCCESS; 01482 } 01483 01484 ///////////////////////////////////////////////////////////////////////////////////////////////// 01485 ErrorCode HalfFacetRep::get_down_adjacencies_2d( EntityHandle fid, std::vector< EntityHandle >& adjents ) 01486 { 01487 // Returns explicit edges, if any, of the face 01488 ErrorCode error; 01489 adjents.reserve( 10 ); 01490 EntityType ftype = mb->type_from_handle( fid ); 01491 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 01492 01493 const EntityHandle* conn; 01494 error = mb->get_connectivity( fid, conn, nepf, true );MB_CHK_ERR( error ); 01495 01496 std::vector< EntityHandle > temp; 01497 01498 // Loop over 2 vertices 01499 for( int i = 0; i < 2; i++ ) 01500 { 01501 // Choose the two adjacent vertices for a triangle, and two opposite vertices for a quad 01502 int l; 01503 if( ftype == MBTRI ) 01504 l = i; 01505 else 01506 l = 2 * i; 01507 01508 // Get the current, next and prev vertices 01509 int nidx = lConnMap2D[ftype - 2].next[l]; 01510 int pidx = lConnMap2D[ftype - 2].prev[l]; 01511 EntityHandle v = conn[l]; 01512 EntityHandle vnext = conn[nidx]; 01513 EntityHandle vprev = conn[pidx]; 01514 01515 // Get incident edges on v 01516 error = get_up_adjacencies_1d( v, temp );MB_CHK_ERR( error ); 01517 01518 // Loop over the incident edges and check if its end vertices match those in the face 01519 for( int k = 0; k < (int)temp.size(); k++ ) 01520 { 01521 const EntityHandle* econn; 01522 int num_conn = 0; 01523 error = mb->get_connectivity( temp[k], econn, num_conn, true );MB_CHK_ERR( error ); 01524 01525 if( ( econn[0] == v && econn[1] == vnext ) || ( econn[0] == v && econn[1] == vprev ) || 01526 ( econn[0] == vnext && econn[1] == v ) || ( econn[0] == vprev && econn[1] == v ) ) 01527 { 01528 bool found = false; 01529 for( int j = 0; j < (int)adjents.size(); j++ ) 01530 { 01531 if( adjents[j] == temp[k] ) 01532 { 01533 found = true; 01534 break; 01535 } 01536 } 01537 if( !found ) adjents.push_back( temp[k] ); 01538 } 01539 } 01540 } 01541 01542 return MB_SUCCESS; 01543 } 01544 01545 //////////////////////////////////////////////////////////////////////////////////////////////// 01546 int HalfFacetRep::find_total_edges_2d( Range& faces ) 01547 { 01548 ErrorCode error; 01549 EntityType ftype = mb->type_from_handle( *faces.begin() ); 01550 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 01551 int nfaces = faces.size(); 01552 01553 int total_edges = nepf * nfaces; 01554 01555 std::vector< int > trackF( total_edges, 0 ); 01556 std::vector< EntityHandle > adj_fids; 01557 std::vector< int > adj_lids; 01558 01559 for( Range::iterator f = faces.begin(); f != faces.end(); ++f ) 01560 { 01561 for( int l = 0; l < nepf; l++ ) 01562 { 01563 01564 adj_fids.clear(); 01565 adj_lids.clear(); 01566 01567 int id = nepf * ( faces.index( *f ) ) + l; 01568 if( !trackF[id] ) 01569 { 01570 error = get_up_adjacencies_2d( *f, l, false, adj_fids, &adj_lids );MB_CHK_ERR( error ); 01571 01572 total_edges -= adj_fids.size(); 01573 01574 for( int i = 0; i < (int)adj_fids.size(); i++ ) 01575 trackF[nepf * ( faces.index( adj_fids[i] ) ) + adj_lids[i]] = 1; 01576 }; 01577 }; 01578 }; 01579 01580 return total_edges; 01581 } 01582 01583 ErrorCode HalfFacetRep::get_face_edges( EntityHandle fid, std::vector< EntityHandle >& edges ) 01584 { 01585 ErrorCode error; 01586 edges.clear(); 01587 01588 EntityType ftype = mb->type_from_handle( fid ); 01589 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 01590 01591 std::vector< EntityHandle > conn; 01592 error = mb->get_connectivity( &fid, 1, conn );MB_CHK_ERR( error ); 01593 01594 for( int i = 0; i < nepf; i++ ) 01595 { 01596 EntityHandle v0 = conn[i]; 01597 EntityHandle v1 = conn[lConnMap2D[ftype - 2].next[i]]; 01598 01599 std::vector< EntityHandle > e0, e1, ecom; 01600 error = get_up_adjacencies_1d( v0, e0 );MB_CHK_ERR( error ); 01601 error = get_up_adjacencies_1d( v1, e1 );MB_CHK_ERR( error ); 01602 01603 std::sort( e0.begin(), e0.end() ); 01604 std::sort( e1.begin(), e1.end() ); 01605 std::set_intersection( e0.begin(), e0.end(), e1.begin(), e1.end(), std::back_inserter( ecom ) ); 01606 assert( ecom.size() == 1 || ecom.size() == 0 ); 01607 if( ecom.size() == 0 ) 01608 edges.push_back( 0 ); 01609 else 01610 edges.push_back( ecom[0] ); 01611 } 01612 01613 return MB_SUCCESS; 01614 } 01615 01616 /******************************************************* 01617 * 3D: sibhfs, v2hf, incident and neighborhood queries * 01618 ********************************************************/ 01619 01620 int HalfFacetRep::get_index_in_lmap( EntityHandle cid ) 01621 { 01622 EntityType type = mb->type_from_handle( cid ); 01623 int index = cell_index.find( type )->second; 01624 return index; 01625 } 01626 01627 const HalfFacetRep::LocalMaps3D HalfFacetRep::lConnMap3D[4] = { 01628 // Tet 01629 { 4, 01630 6, 01631 4, 01632 { 3, 3, 3, 3 }, 01633 { { 0, 1, 3 }, { 1, 2, 3 }, { 2, 0, 3 }, { 0, 2, 1 } }, 01634 { 3, 3, 3, 3 }, 01635 { { 0, 2, 3 }, { 0, 1, 3 }, { 1, 2, 3 }, { 0, 1, 2 } }, 01636 { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 3 }, { 2, 3 } }, 01637 { { 3, 0 }, { 3, 1 }, { 3, 2 }, { 0, 2 }, { 0, 1 }, { 1, 2 } }, 01638 { { 0, 4, 3 }, { 1, 5, 4 }, { 2, 3, 5 }, { 2, 1, 0 } }, 01639 { { -1, 0, 2, 3 }, { 0, -1, 1, 4 }, { 2, 1, -1, 5 }, { 3, 4, 5, -1 } }, 01640 { 3, 0, 1, 2 }, 01641 { 0, 1 }, 01642 { { 3, 1, 2, 3 }, { 2, 2, 3 }, { 1, 3 } } }, 01643 01644 // Pyramid: Note: In MOAB pyramid follows the CGNS convention. Look up src/MBCNArrays.hpp 01645 { 5, 01646 8, 01647 5, 01648 { 4, 3, 3, 3, 3 }, 01649 { { 0, 3, 2, 1 }, { 0, 1, 4 }, { 1, 2, 4 }, { 2, 3, 4 }, { 3, 0, 4 } }, 01650 { 3, 3, 3, 3, 4 }, 01651 { { 0, 1, 4 }, { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 4 }, { 1, 2, 3, 4 } }, 01652 { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 4 }, { 2, 4 }, { 3, 4 } }, 01653 { { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 1, 4 }, { 1, 2 }, { 2, 3 }, { 3, 4 } }, 01654 { { 3, 2, 1, 0 }, { 0, 5, 4 }, { 1, 6, 5 }, { 2, 7, 6 }, { 3, 4, 7 } }, 01655 { { -1, 0, -1, 3, 4 }, { 0, -1, 1, -1, 5 }, { -1, 1, -1, 2, 6 }, { 3, -1, 2, -1, 7 }, { 4, 5, 6, 7, -1 } }, 01656 { 3, 4, 2, 0 }, 01657 { 0, 4 }, 01658 { { 4, 0, 1, 2, 3 }, { 2, 1, 3 }, { 2, 1, 3 } } }, 01659 01660 // Prism 01661 { 6, 01662 9, 01663 5, 01664 { 4, 4, 4, 3, 3 }, 01665 { { 0, 1, 4, 3 }, { 1, 2, 5, 4 }, { 0, 3, 5, 2 }, { 0, 2, 1 }, { 3, 4, 5 } }, 01666 { 3, 3, 3, 3, 3, 3 }, 01667 { { 0, 2, 3 }, { 0, 1, 3 }, { 1, 2, 3 }, { 0, 2, 4 }, { 0, 1, 4 }, { 1, 4, 2 } }, 01668 { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 4 }, { 2, 5 }, { 3, 4 }, { 4, 5 }, { 5, 3 } }, 01669 { { 0, 3 }, { 1, 3 }, { 2, 3 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 4 }, { 1, 4 }, { 2, 4 } }, 01670 { { 0, 4, 6, 3 }, { 1, 5, 7, 4 }, { 2, 3, 8, 5 }, { 2, 1, 0 }, { 6, 7, 8 } }, 01671 { { -1, 0, 2, 3, -1, -1 }, 01672 { 0, -1, 1, -1, 4, -1 }, 01673 { 2, 1, -1, -1, -1, 5 }, 01674 { 3, -1, -1, -1, 6, 8 }, 01675 { -1, 4, -1, 6, -1, 7 }, 01676 { -1, -1, 5, 8, 7, -1 } }, 01677 { 4, 0, 5, 4, 1 }, 01678 { 0, 5 }, 01679 { { 3, 1, 2, 3 }, { 3, 2, 4, 3 }, { 2, 3, 1 }, { 1, 2 } } }, 01680 01681 // Hex 01682 { 8, 01683 12, 01684 6, 01685 { 4, 4, 4, 4, 4, 4 }, 01686 { { 0, 1, 5, 4 }, { 1, 2, 6, 5 }, { 2, 3, 7, 6 }, { 3, 0, 4, 7 }, { 0, 3, 2, 1 }, { 4, 5, 6, 7 } }, 01687 { 3, 3, 3, 3, 3, 3, 3, 3 }, 01688 { { 0, 3, 4 }, { 0, 1, 4 }, { 1, 2, 4 }, { 2, 3, 4 }, { 0, 3, 5 }, { 0, 1, 5 }, { 1, 2, 5 }, { 2, 3, 5 } }, 01689 { { 0, 1 }, 01690 { 1, 2 }, 01691 { 2, 3 }, 01692 { 3, 0 }, 01693 { 0, 4 }, 01694 { 1, 5 }, 01695 { 2, 6 }, 01696 { 3, 7 }, 01697 { 4, 5 }, 01698 { 5, 6 }, 01699 { 6, 7 }, 01700 { 7, 4 } }, 01701 { { 0, 4 }, 01702 { 1, 4 }, 01703 { 2, 4 }, 01704 { 3, 4 }, 01705 { 0, 3 }, 01706 { 0, 1 }, 01707 { 1, 2 }, 01708 { 2, 3 }, 01709 { 0, 5 }, 01710 { 1, 5 }, 01711 { 2, 5 }, 01712 { 3, 5 } }, 01713 { { 0, 5, 8, 4 }, { 1, 6, 9, 5 }, { 2, 7, 10, 6 }, { 3, 4, 11, 7 }, { 3, 2, 1, 0 }, { 8, 9, 10, 11 } }, 01714 { { -1, 0, -1, 3, 4, -1, -1, -1 }, 01715 { 0, -1, 1, -1, -1, 5, -1, -1 }, 01716 { -1, 1, -1, 2, -1, -1, 6, -1 }, 01717 { 3, -1, 2, -1, -1, -1, -1, 7 }, 01718 { 4, -1, -1, -1, -1, 8, -1, 11 }, 01719 { -1, 5, -1, -1, 8, -1, 9, -1 }, 01720 { -1, -1, 6, -1, -1, 9, -1, 10 }, 01721 { -1, -1, -1, 7, 11, -1, 10, -1 } }, 01722 { 4, 0, 2, 5, 7 }, 01723 { 0, 6 }, 01724 { { 3, 1, 3, 4 }, { 3, 1, 3, 6 }, { 3, 1, 4, 6 }, { 3, 3, 6, 4 } } } }; 01725 01726 ////////////////////////////////////////////////////////////////////////////////// 01727 ErrorCode HalfFacetRep::determine_sibling_halffaces( Range& cells ) 01728 { 01729 ErrorCode error; 01730 EntityHandle start_cell = *cells.begin(); 01731 EntityType ctype = mb->type_from_handle( start_cell ); 01732 int index = get_index_in_lmap( start_cell ); 01733 int nvpc = lConnMap3D[index].num_verts_in_cell; 01734 int nfpc = lConnMap3D[index].num_faces_in_cell; 01735 01736 // Step 1: Create an index list storing the starting position for each vertex 01737 int nv = _verts.size(); 01738 std::vector< int > is_index( nv + 1 ); 01739 for( int i = 0; i < nv + 1; i++ ) 01740 is_index[i] = 0; 01741 01742 int vindex; 01743 01744 for( Range::iterator cid = cells.begin(); cid != cells.end(); ++cid ) 01745 { 01746 const EntityHandle* conn; 01747 error = mb->get_connectivity( *cid, conn, nvpc, true );MB_CHK_ERR( error ); 01748 01749 for( int i = 0; i < nfpc; ++i ) 01750 { 01751 int nvF = lConnMap3D[index].hf2v_num[i]; 01752 EntityHandle v = 0; 01753 for( int k = 0; k < nvF; k++ ) 01754 { 01755 int id = lConnMap3D[index].hf2v[i][k]; 01756 if( v <= conn[id] ) v = conn[id]; 01757 } 01758 vindex = _verts.index( v ); 01759 is_index[vindex + 1] += 1; 01760 } 01761 } 01762 is_index[0] = 0; 01763 01764 for( int i = 0; i < nv; i++ ) 01765 is_index[i + 1] = is_index[i] + is_index[i + 1]; 01766 01767 // Step 2: Define four arrays v2hv_eid, v2hv_lvid storing every half-facet on a vertex 01768 std::vector< EntityHandle > v2oe_v1( is_index[nv] ); 01769 std::vector< EntityHandle > v2oe_v2( is_index[nv] ); 01770 std::vector< EntityHandle > v2hf_map_cid( is_index[nv] ); 01771 std::vector< int > v2hf_map_lfid( is_index[nv] ); 01772 01773 for( Range::iterator cid = cells.begin(); cid != cells.end(); ++cid ) 01774 { 01775 const EntityHandle* conn; 01776 error = mb->get_connectivity( *cid, conn, nvpc, true );MB_CHK_ERR( error ); 01777 01778 for( int i = 0; i < nfpc; i++ ) 01779 { 01780 int nvF = lConnMap3D[index].hf2v_num[i]; 01781 std::vector< EntityHandle > vs( nvF ); 01782 EntityHandle vmax = 0; 01783 int lv = -1; 01784 for( int k = 0; k < nvF; k++ ) 01785 { 01786 int id = lConnMap3D[index].hf2v[i][k]; 01787 vs[k] = conn[id]; 01788 if( vmax <= conn[id] ) 01789 { 01790 vmax = conn[id]; 01791 lv = k; 01792 } 01793 } 01794 01795 int nidx = lConnMap2D[nvF - 3].next[lv]; 01796 int pidx = lConnMap2D[nvF - 3].prev[lv]; 01797 01798 int v = _verts.index( vmax ); 01799 v2oe_v1[is_index[v]] = vs[nidx]; 01800 v2oe_v2[is_index[v]] = vs[pidx]; 01801 v2hf_map_cid[is_index[v]] = *cid; 01802 v2hf_map_lfid[is_index[v]] = i; 01803 is_index[v] += 1; 01804 } 01805 } 01806 01807 for( int i = nv - 2; i >= 0; i-- ) 01808 is_index[i + 1] = is_index[i]; 01809 is_index[0] = 0; 01810 01811 // Step 3: Fill up sibling half-verts map 01812 for( Range::iterator cid = cells.begin(); cid != cells.end(); ++cid ) 01813 { 01814 const EntityHandle* conn; 01815 error = mb->get_connectivity( *cid, conn, nvpc, true );MB_CHK_ERR( error ); 01816 01817 int cidx = ID_FROM_HANDLE( *cid ) - 1; 01818 for( int i = 0; i < nfpc; i++ ) 01819 { 01820 HFacet hf = sibhfs[nfpc * cidx + i]; 01821 EntityHandle sibcid = fid_from_halfacet( hf, ctype ); 01822 01823 if( sibcid != 0 ) continue; 01824 01825 int nvF = lConnMap3D[index].hf2v_num[i]; 01826 std::vector< EntityHandle > vs( nvF ); 01827 EntityHandle vmax = 0; 01828 int lv = -1; 01829 for( int k = 0; k < nvF; k++ ) 01830 { 01831 int id = lConnMap3D[index].hf2v[i][k]; 01832 vs[k] = conn[id]; 01833 if( vmax <= conn[id] ) 01834 { 01835 vmax = conn[id]; 01836 lv = k; 01837 } 01838 } 01839 if( lv < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex " ); 01840 int nidx = lConnMap2D[nvF - 3].next[lv]; 01841 int pidx = lConnMap2D[nvF - 3].prev[lv]; 01842 01843 int v = _verts.index( vmax ); 01844 EntityHandle v1 = vs[pidx]; 01845 EntityHandle v2 = vs[nidx]; 01846 01847 for( int ind = is_index[v]; ind <= is_index[v + 1] - 1; ind++ ) 01848 { 01849 if( ( v2oe_v1[ind] == v1 ) && ( v2oe_v2[ind] == v2 ) ) 01850 { 01851 // Map to opposite hf 01852 EntityHandle cur_cid = v2hf_map_cid[ind]; 01853 int cur_lfid = v2hf_map_lfid[ind]; 01854 01855 sibhfs[nfpc * cidx + i] = create_halffacet( cur_cid, cur_lfid ); 01856 01857 int scidx = ID_FROM_HANDLE( cur_cid ) - 1; 01858 sibhfs[nfpc * scidx + cur_lfid] = create_halffacet( *cid, i ); 01859 } 01860 } 01861 } 01862 } 01863 01864 return MB_SUCCESS; 01865 } 01866 01867 ErrorCode HalfFacetRep::determine_incident_halffaces( Range& cells ) 01868 { 01869 ErrorCode error; 01870 int index = get_index_in_lmap( *cells.begin() ); 01871 int nvpc = lConnMap3D[index].num_verts_in_cell; 01872 01873 std::multimap< EntityHandle, EntityHandle > comps; 01874 HFacet nwhf; 01875 01876 for( Range::iterator cid = cells.begin(); cid != cells.end(); ++cid ) 01877 { 01878 EntityHandle cell = *cid; 01879 const EntityHandle* conn; 01880 error = mb->get_connectivity( *cid, conn, nvpc, true );MB_CHK_ERR( error ); 01881 01882 for( int i = 0; i < nvpc; ++i ) 01883 { 01884 EntityHandle v = conn[i]; 01885 int vidx = ID_FROM_HANDLE( v ) - 1; 01886 HFacet hf = v2hf[vidx]; 01887 01888 bool found = find_cell_in_component( v, cell, comps ); 01889 01890 if( hf == 0 && !found && ( v2hfs.empty() || ( v2hfs.find( v ) == v2hfs.end() ) ) ) 01891 { 01892 nwhf = 0; 01893 error = add_cells_of_single_component( v, cell, lConnMap3D[index].v2hf[i][0], comps, nwhf );MB_CHK_ERR( error ); 01894 01895 v2hf[vidx] = nwhf; 01896 } 01897 else if( hf != 0 && !found ) 01898 { 01899 nwhf = 0; 01900 error = add_cells_of_single_component( v, cell, lConnMap3D[index].v2hf[i][0], comps, nwhf );MB_CHK_ERR( error ); 01901 01902 v2hfs.insert( std::pair< EntityHandle, HFacet >( v, hf ) ); 01903 v2hfs.insert( std::pair< EntityHandle, HFacet >( v, nwhf ) ); 01904 v2hf[vidx] = 0; 01905 } 01906 else if( hf == 0 && !found && ( !v2hfs.empty() ) && ( v2hfs.find( v ) != v2hfs.end() ) ) 01907 { 01908 nwhf = 0; 01909 error = add_cells_of_single_component( v, cell, lConnMap3D[index].v2hf[i][0], comps, nwhf );MB_CHK_ERR( error ); 01910 v2hfs.insert( std::pair< EntityHandle, HFacet >( v, nwhf ) ); 01911 } 01912 } 01913 } 01914 01915 // error = print_tags(3); 01916 01917 return MB_SUCCESS; 01918 } 01919 01920 ErrorCode HalfFacetRep::determine_border_vertices( Range& cells, Tag isborder ) 01921 { 01922 ErrorCode error; 01923 EntityHandle start_cell = *cells.begin(); 01924 EntityType ctype = mb->type_from_handle( *cells.begin() ); 01925 int index = get_index_in_lmap( start_cell ); 01926 int nvpc = lConnMap3D[index].num_verts_in_cell; 01927 int nfpc = lConnMap3D[index].num_faces_in_cell; 01928 01929 int val = 1; 01930 01931 for( Range::iterator t = cells.begin(); t != cells.end(); ++t ) 01932 { 01933 01934 const EntityHandle* conn; 01935 error = mb->get_connectivity( *t, conn, nvpc, true );MB_CHK_ERR( error ); 01936 01937 int cidx = ID_FROM_HANDLE( *t ) - 1; 01938 for( int i = 0; i < nfpc; ++i ) 01939 { 01940 HFacet hf = sibhfs[nfpc * cidx + i]; 01941 EntityHandle sib_cid = fid_from_halfacet( hf, ctype ); 01942 01943 if( sib_cid == 0 ) 01944 { 01945 int nvF = lConnMap3D[index].hf2v_num[i]; 01946 01947 for( int j = 0; j < nvF; ++j ) 01948 { 01949 int ind = lConnMap3D[index].hf2v[i][j]; 01950 error = mb->tag_set_data( isborder, &conn[ind], 1, &val );MB_CHK_ERR( error ); 01951 } 01952 } 01953 } 01954 } 01955 01956 return MB_SUCCESS; 01957 } 01958 01959 ///////////////////////////////////////////////////////////////////////// 01960 ErrorCode HalfFacetRep::add_cells_of_single_component( EntityHandle vid, 01961 EntityHandle curcid, 01962 int curlid, 01963 std::multimap< EntityHandle, EntityHandle >& comps, 01964 HFacet& hf ) 01965 { 01966 ErrorCode error; 01967 EntityType ctype = mb->type_from_handle( curcid ); 01968 int index = get_index_in_lmap( curcid ); 01969 int nvpc = lConnMap3D[index].num_verts_in_cell; 01970 int nfpc = lConnMap3D[index].num_faces_in_cell; 01971 01972 int Stksize = 0, count = -1; 01973 Stkcells[0] = curcid; 01974 01975 hf = create_halffacet( curcid, curlid ); 01976 01977 EntityHandle cur_cid; 01978 while( Stksize >= 0 ) 01979 { 01980 cur_cid = Stkcells[Stksize]; 01981 Stksize -= 1; 01982 01983 bool found = find_match_in_array( cur_cid, trackcells, count ); 01984 if( !found ) 01985 { 01986 count += 1; 01987 trackcells[count] = cur_cid; 01988 01989 // Add the current cell 01990 comps.insert( std::pair< EntityHandle, EntityHandle >( vid, cur_cid ) ); 01991 } 01992 01993 // Connectivity of the cell 01994 const EntityHandle* conn; 01995 error = mb->get_connectivity( cur_cid, conn, nvpc, true );MB_CHK_ERR( error ); 01996 01997 // Local id of vid in the cell and the half-faces incident on it 01998 int lv = -1; 01999 for( int i = 0; i < nvpc; ++i ) 02000 { 02001 if( conn[i] == vid ) 02002 { 02003 lv = i; 02004 break; 02005 } 02006 } 02007 if( lv < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex " ); 02008 int nhf_thisv = lConnMap3D[index].v2hf_num[lv]; 02009 int cidx = ID_FROM_HANDLE( cur_cid ) - 1; 02010 02011 // Add new cells into the stack 02012 EntityHandle ngb; 02013 HFacet hf_ngb; 02014 for( int i = 0; i < nhf_thisv; ++i ) 02015 { 02016 int ind = lConnMap3D[index].v2hf[lv][i]; 02017 hf_ngb = sibhfs[nfpc * cidx + ind]; 02018 ngb = fid_from_halfacet( hf_ngb, ctype ); 02019 02020 if( ngb ) 02021 { 02022 bool found_ent = find_match_in_array( ngb, trackcells, count ); 02023 02024 if( !found_ent ) 02025 { 02026 Stksize += 1; 02027 Stkcells[Stksize] = ngb; 02028 } 02029 } 02030 else 02031 hf = create_halffacet( cur_cid, ind ); 02032 } 02033 } 02034 02035 // Change the visited faces to false 02036 for( int i = 0; i < Stksize; i++ ) 02037 Stkcells[i] = 0; 02038 02039 for( int i = 0; i <= count; i++ ) 02040 trackcells[i] = 0; 02041 02042 return MB_SUCCESS; 02043 } 02044 02045 bool HalfFacetRep::find_cell_in_component( EntityHandle vid, 02046 EntityHandle cell, 02047 std::multimap< EntityHandle, EntityHandle >& comps ) 02048 { 02049 bool found = false; 02050 02051 if( comps.empty() ) return found; 02052 02053 std::pair< std::multimap< EntityHandle, EntityHandle >::iterator, 02054 std::multimap< EntityHandle, EntityHandle >::iterator > 02055 rit; 02056 02057 rit = comps.equal_range( vid ); 02058 02059 for( std::multimap< EntityHandle, EntityHandle >::iterator it = rit.first; it != rit.second; ++it ) 02060 { 02061 if( it->second == cell ) 02062 { 02063 found = true; 02064 break; 02065 } 02066 } 02067 02068 return found; 02069 } 02070 02071 //////////////////////////////////////////////////////////////////////// 02072 ErrorCode HalfFacetRep::get_up_adjacencies_vert_3d( EntityHandle vid, std::vector< EntityHandle >& adjents ) 02073 { 02074 ErrorCode error; 02075 adjents.reserve( 20 ); 02076 EntityType ctype = mb->type_from_handle( *_cells.begin() ); 02077 02078 // Obtain a half-face/s incident on v 02079 int vidx = ID_FROM_HANDLE( vid ) - 1; 02080 HFacet hf = v2hf[vidx]; 02081 02082 std::vector< EntityHandle > start_cells; 02083 if( hf == 0 && ( v2hfs.find( vid ) != v2hfs.end() ) ) // Vertex is non-manifold 02084 { 02085 std::pair< std::multimap< EntityHandle, HFacet >::iterator, std::multimap< EntityHandle, HFacet >::iterator > 02086 it_hes; 02087 it_hes = v2hfs.equal_range( vid ); 02088 02089 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 02090 { 02091 start_cells.push_back( fid_from_halfacet( it->second, ctype ) ); 02092 } 02093 } 02094 else if( hf != 0 ) 02095 start_cells.push_back( fid_from_halfacet( hf, ctype ) ); 02096 02097 if( start_cells.empty() ) return MB_SUCCESS; 02098 02099 int index = get_index_in_lmap( start_cells[0] ); 02100 int nvpc = lConnMap3D[index].num_verts_in_cell; 02101 int nfpc = lConnMap3D[index].num_faces_in_cell; 02102 02103 for( int i = 0; i < (int)start_cells.size(); i++ ) 02104 cellq[i] = start_cells[i]; 02105 02106 int qsize = start_cells.size(); 02107 EntityHandle cur_cid; 02108 int num_qvals = 0; 02109 02110 while( num_qvals < qsize ) 02111 { 02112 cur_cid = cellq[num_qvals]; 02113 num_qvals += 1; 02114 02115 // Add the current cell to output adj vector 02116 adjents.push_back( cur_cid ); 02117 02118 // Connectivity of the cell 02119 const EntityHandle* conn; 02120 error = mb->get_connectivity( cur_cid, conn, nvpc, true );MB_CHK_ERR( error ); 02121 02122 // Local id of vid in the cell and the half-faces incident on it 02123 int lv = -1; 02124 for( int i = 0; i < nvpc; ++i ) 02125 { 02126 if( conn[i] == vid ) 02127 { 02128 lv = i; 02129 break; 02130 } 02131 }; 02132 if( lv < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex " ); 02133 // Number of local half-faces incident on the current vertex 02134 int nhf_thisv = lConnMap3D[index].v2hf_num[lv]; 02135 int cidx = ID_FROM_HANDLE( cur_cid ) - 1; 02136 02137 // Add new cells into the stack 02138 EntityHandle ngb; 02139 for( int i = 0; i < nhf_thisv; ++i ) 02140 { 02141 int ind = lConnMap3D[index].v2hf[lv][i]; 02142 hf = sibhfs[nfpc * cidx + ind]; 02143 ngb = fid_from_halfacet( hf, ctype ); 02144 02145 if( ngb ) 02146 { 02147 bool found_ent = find_match_in_array( ngb, cellq, qsize - 1 ); 02148 02149 if( !found_ent ) 02150 { 02151 cellq[qsize] = ngb; 02152 qsize += 1; 02153 } 02154 } 02155 } 02156 } 02157 02158 // Change the visited faces to false 02159 for( int i = 0; i < qsize; i++ ) 02160 cellq[i] = 0; 02161 02162 return MB_SUCCESS; 02163 } 02164 02165 ErrorCode HalfFacetRep::get_up_adjacencies_edg_3d( EntityHandle eid, 02166 std::vector< EntityHandle >& adjents, 02167 std::vector< int >* leids ) 02168 { 02169 ErrorCode error; 02170 EntityType ctype = mb->type_from_handle( *_cells.begin() ); 02171 EntityHandle start_cell = *_cells.begin(); 02172 int index = get_index_in_lmap( start_cell ); 02173 int nvpc = lConnMap3D[index].num_verts_in_cell; 02174 int nfpc = lConnMap3D[index].num_faces_in_cell; 02175 02176 adjents.reserve( 20 ); 02177 if( leids != NULL ) leids->reserve( 20 ); 02178 02179 // Find the edge vertices 02180 const EntityHandle* econn; 02181 int num_conn = 0; 02182 error = mb->get_connectivity( eid, econn, num_conn, true );MB_CHK_ERR( error ); 02183 02184 EntityHandle v_start = econn[0], v_end = econn[1]; 02185 int v1idx = ID_FROM_HANDLE( v_start ) - 1; 02186 int v2idx = ID_FROM_HANDLE( v_end ) - 1; 02187 02188 // Find an half-facets incident to each end vertex of the edge 02189 std::vector< EntityHandle > start_cells; 02190 HFacet hf1 = v2hf[v1idx]; 02191 HFacet hf2 = v2hf[v2idx]; 02192 02193 if( hf1 == 0 && !v2hfs.empty() ) 02194 { 02195 std::pair< std::multimap< EntityHandle, HFacet >::iterator, std::multimap< EntityHandle, HFacet >::iterator > 02196 it_hes; 02197 it_hes = v2hfs.equal_range( v_start ); 02198 02199 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 02200 { 02201 start_cells.push_back( fid_from_halfacet( it->second, ctype ) ); 02202 } 02203 } 02204 else if( hf1 != 0 ) 02205 { 02206 start_cells.push_back( fid_from_halfacet( hf1, ctype ) ); 02207 } 02208 02209 if( hf2 == 0 && !v2hfs.empty() ) 02210 { 02211 std::pair< std::multimap< EntityHandle, HFacet >::iterator, std::multimap< EntityHandle, HFacet >::iterator > 02212 it_hes; 02213 it_hes = v2hfs.equal_range( v_end ); 02214 02215 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 02216 { 02217 start_cells.push_back( fid_from_halfacet( it->second, ctype ) ); 02218 } 02219 } 02220 else if( hf2 != 0 ) 02221 { 02222 start_cells.push_back( fid_from_halfacet( hf2, ctype ) ); 02223 } 02224 02225 if( start_cells.empty() ) return MB_SUCCESS; 02226 02227 std::sort( start_cells.begin(), start_cells.end() ); 02228 std::vector< EntityHandle >::iterator last = std::unique( start_cells.begin(), start_cells.end() ); 02229 start_cells.erase( last, start_cells.end() ); 02230 02231 for( int i = 0; i < (int)start_cells.size(); i++ ) 02232 cellq[i] = start_cells[i]; 02233 02234 int qsize = start_cells.size(); 02235 int num_qvals = 0; 02236 02237 while( num_qvals < qsize ) 02238 { 02239 EntityHandle cell_id = cellq[num_qvals]; 02240 num_qvals += 1; 02241 02242 const EntityHandle* conn; 02243 error = mb->get_connectivity( cell_id, conn, nvpc, true );MB_CHK_ERR( error ); 02244 02245 int lv0 = -1, lv1 = -1, lv = -1; 02246 02247 // locate v_origin in poped out tet, check if v_end is in 02248 for( int i = 0; i < nvpc; i++ ) 02249 { 02250 if( v_start == conn[i] ) 02251 { 02252 lv0 = i; 02253 lv = lv0; 02254 } 02255 else if( v_end == conn[i] ) 02256 { 02257 lv1 = i; 02258 lv = lv1; 02259 } 02260 } 02261 02262 if( ( lv0 >= 0 ) && ( lv1 >= 0 ) ) 02263 { 02264 adjents.push_back( cell_id ); 02265 if( leids != NULL ) leids->push_back( lConnMap3D[index].lookup_leids[lv0][lv1] ); 02266 } 02267 02268 // push back new found unchecked incident tets of v_start 02269 int cidx = ID_FROM_HANDLE( cell_id ) - 1; 02270 if( lv < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex " ); 02271 int nhf_thisv = lConnMap3D[index].v2hf_num[lv]; 02272 02273 for( int i = 0; i < nhf_thisv; i++ ) 02274 { 02275 int ind = lConnMap3D[index].v2hf[lv][i]; 02276 HFacet hf = sibhfs[nfpc * cidx + ind]; 02277 EntityHandle ngb = fid_from_halfacet( hf, ctype ); 02278 02279 if( ngb ) 02280 { 02281 bool found_ent = find_match_in_array( ngb, &cellq[0], qsize - 1 ); 02282 02283 if( !found_ent ) 02284 { 02285 cellq[qsize] = ngb; 02286 qsize += 1; 02287 } 02288 } 02289 } 02290 } 02291 02292 for( int i = 0; i < qsize; i++ ) 02293 cellq[i] = 0; 02294 02295 return MB_SUCCESS; 02296 } 02297 02298 ErrorCode HalfFacetRep::get_up_adjacencies_edg_3d( EntityHandle cid, 02299 int leid, 02300 std::vector< EntityHandle >& adjents, 02301 std::vector< int >* leids, 02302 std::vector< int >* adj_orients ) 02303 { 02304 ErrorCode error; 02305 EntityType ctype = mb->type_from_handle( cid ); 02306 int index = get_index_in_lmap( cid ); 02307 int nvpc = lConnMap3D[index].num_verts_in_cell; 02308 int nfpc = lConnMap3D[index].num_faces_in_cell; 02309 adjents.clear(); 02310 adjents.reserve( 20 ); 02311 02312 if( leids != NULL ) 02313 { 02314 leids->clear(); 02315 leids->reserve( 20 ); 02316 } 02317 if( adj_orients != NULL ) 02318 { 02319 adj_orients->clear(); 02320 adj_orients->reserve( 20 ); 02321 } 02322 02323 const EntityHandle* econn; 02324 error = mb->get_connectivity( cid, econn, nvpc, true );MB_CHK_ERR( error ); 02325 02326 // Get the end vertices of the edge <cid,leid> 02327 int id = lConnMap3D[index].e2v[leid][0]; 02328 EntityHandle v_start = econn[id]; 02329 id = lConnMap3D[index].e2v[leid][1]; 02330 EntityHandle v_end = econn[id]; 02331 02332 int v1idx = ID_FROM_HANDLE( v_start ) - 1; 02333 int v2idx = ID_FROM_HANDLE( v_end ) - 1; 02334 02335 // Find an half-facets incident to each end vertex of the edge 02336 std::vector< EntityHandle > start_cells; 02337 HFacet hf1 = v2hf[v1idx]; 02338 HFacet hf2 = v2hf[v2idx]; 02339 02340 if( hf1 == 0 && !v2hfs.empty() ) 02341 { 02342 std::pair< std::multimap< EntityHandle, HFacet >::iterator, std::multimap< EntityHandle, HFacet >::iterator > 02343 it_hes; 02344 it_hes = v2hfs.equal_range( v_start ); 02345 02346 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 02347 { 02348 start_cells.push_back( fid_from_halfacet( it->second, ctype ) ); 02349 } 02350 } 02351 else if( hf1 != 0 ) 02352 { 02353 start_cells.push_back( fid_from_halfacet( hf1, ctype ) ); 02354 } 02355 02356 if( hf2 == 0 && !v2hfs.empty() ) 02357 { 02358 std::pair< std::multimap< EntityHandle, HFacet >::iterator, std::multimap< EntityHandle, HFacet >::iterator > 02359 it_hes; 02360 it_hes = v2hfs.equal_range( v_end ); 02361 02362 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 02363 { 02364 start_cells.push_back( fid_from_halfacet( it->second, ctype ) ); 02365 } 02366 } 02367 else if( hf2 != 0 ) 02368 { 02369 start_cells.push_back( fid_from_halfacet( hf2, ctype ) ); 02370 } 02371 02372 if( start_cells.empty() ) return MB_SUCCESS; 02373 02374 std::sort( start_cells.begin(), start_cells.end() ); 02375 std::vector< EntityHandle >::iterator last = std::unique( start_cells.begin(), start_cells.end() ); 02376 start_cells.erase( last, start_cells.end() ); 02377 02378 for( int i = 0; i < (int)start_cells.size(); i++ ) 02379 cellq[i] = start_cells[i]; 02380 02381 int qsize = start_cells.size(); 02382 int num_qvals = 0; 02383 02384 while( num_qvals < qsize ) 02385 { 02386 EntityHandle cell_id = cellq[num_qvals]; 02387 num_qvals += 1; 02388 02389 const EntityHandle* conn; 02390 error = mb->get_connectivity( cell_id, conn, nvpc, true );MB_CHK_ERR( error ); 02391 02392 int lv0 = -1, lv1 = -1, lv = -1; 02393 02394 // locate v_origin in poped out tet, check if v_end is in 02395 for( int i = 0; i < nvpc; i++ ) 02396 { 02397 if( v_start == conn[i] ) 02398 { 02399 lv0 = i; 02400 lv = lv0; 02401 } 02402 else if( v_end == conn[i] ) 02403 { 02404 lv1 = i; 02405 lv = lv1; 02406 } 02407 } 02408 02409 if( ( lv0 >= 0 ) && ( lv1 >= 0 ) ) 02410 { 02411 adjents.push_back( cell_id ); 02412 if( leids != NULL ) leids->push_back( lConnMap3D[index].lookup_leids[lv0][lv1] ); 02413 02414 if( adj_orients != NULL ) 02415 { 02416 int cur_leid = lConnMap3D[index].lookup_leids[lv0][lv1]; 02417 int id1 = lConnMap3D[index].e2v[cur_leid][0]; 02418 int id2 = lConnMap3D[index].e2v[cur_leid][1]; 02419 if( ( v_start == conn[id1] ) && ( v_end == conn[id2] ) ) 02420 adj_orients->push_back( 1 ); 02421 else if( ( v_start == conn[id2] ) && ( v_end == conn[id1] ) ) 02422 adj_orients->push_back( 0 ); 02423 } 02424 } 02425 if( lv < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex " ); 02426 // push back new found unchecked incident tets of v_start 02427 int cidx = ID_FROM_HANDLE( cell_id ) - 1; 02428 int nhf_thisv = lConnMap3D[index].v2hf_num[lv]; 02429 02430 for( int i = 0; i < nhf_thisv; i++ ) 02431 { 02432 int ind = lConnMap3D[index].v2hf[lv][i]; 02433 HFacet hf = sibhfs[nfpc * cidx + ind]; 02434 EntityHandle ngb = fid_from_halfacet( hf, ctype ); 02435 02436 if( ngb ) 02437 { 02438 bool found_ent = find_match_in_array( ngb, &cellq[0], qsize - 1 ); 02439 02440 if( !found_ent ) 02441 { 02442 cellq[qsize] = ngb; 02443 qsize += 1; 02444 } 02445 } 02446 } 02447 } 02448 02449 for( int i = 0; i < qsize; i++ ) 02450 cellq[i] = 0; 02451 02452 return MB_SUCCESS; 02453 } 02454 02455 ErrorCode HalfFacetRep::get_up_adjacencies_edg_3d_comp( EntityHandle cid, 02456 int leid, 02457 std::vector< EntityHandle >& adjents, 02458 std::vector< int >* leids, 02459 std::vector< int >* adj_orients ) 02460 { 02461 ErrorCode error; 02462 EntityType ctype = mb->type_from_handle( cid ); 02463 int index = get_index_in_lmap( cid ); 02464 int nvpc = lConnMap3D[index].num_verts_in_cell; 02465 int nfpc = lConnMap3D[index].num_faces_in_cell; 02466 adjents.clear(); 02467 adjents.reserve( 20 ); 02468 02469 if( leids != NULL ) 02470 { 02471 leids->clear(); 02472 leids->reserve( 20 ); 02473 } 02474 if( adj_orients != NULL ) 02475 { 02476 adj_orients->clear(); 02477 adj_orients->reserve( 20 ); 02478 } 02479 02480 const EntityHandle* econn; 02481 error = mb->get_connectivity( cid, econn, nvpc );MB_CHK_ERR( error ); 02482 02483 // Get the end vertices of the edge <cid,leid> 02484 int id = lConnMap3D[index].e2v[leid][0]; 02485 EntityHandle v_start = econn[id]; 02486 id = lConnMap3D[index].e2v[leid][1]; 02487 EntityHandle v_end = econn[id]; 02488 02489 int v1idx = ID_FROM_HANDLE( v_start ) - 1; 02490 int v2idx = ID_FROM_HANDLE( v_end ) - 1; 02491 02492 // Find an half-facets incident to each end vertex of the edge 02493 std::vector< EntityHandle > start_cells; 02494 HFacet hf1 = v2hf[v1idx]; 02495 HFacet hf2 = v2hf[v2idx]; 02496 02497 if( ( hf1 == 0 ) && ( v2hfs.find( v_start ) != v2hfs.end() ) && ( hf2 == 0 ) && 02498 ( v2hfs.find( v_end ) != v2hfs.end() ) ) 02499 { 02500 std::pair< std::multimap< EntityHandle, HFacet >::iterator, std::multimap< EntityHandle, HFacet >::iterator > 02501 it_hes; 02502 it_hes = v2hfs.equal_range( v_start ); 02503 02504 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 02505 { 02506 start_cells.push_back( fid_from_halfacet( it->second, ctype ) ); 02507 } 02508 } 02509 else 02510 return MB_SUCCESS; 02511 02512 if( start_cells.empty() ) return MB_SUCCESS; 02513 02514 // std::sort(start_cells.begin(), start_cells.end()); 02515 // std::vector<EntityHandle>::iterator last = std::unique(start_cells.begin(), 02516 // start_cells.end()); start_cells.erase(last, start_cells.end()); 02517 02518 for( int c = 0; c < (int)start_cells.size(); c++ ) 02519 { 02520 cellq[0] = start_cells[c]; 02521 02522 int qsize = 1; 02523 int num_qvals = 0; 02524 02525 while( num_qvals < qsize ) 02526 { 02527 EntityHandle cell_id = cellq[num_qvals]; 02528 num_qvals += 1; 02529 02530 const EntityHandle* conn; 02531 error = mb->get_connectivity( cell_id, conn, nvpc );MB_CHK_ERR( error ); 02532 02533 int lv0 = -1, lv1 = -1, lv = -1; 02534 02535 // locate v_origin in poped out tet, check if v_end is in 02536 for( int i = 0; i < nvpc; i++ ) 02537 { 02538 if( v_start == conn[i] ) 02539 { 02540 lv0 = i; 02541 lv = lv0; 02542 } 02543 else if( v_end == conn[i] ) 02544 { 02545 lv1 = i; 02546 lv = lv1; 02547 } 02548 } 02549 02550 if( ( lv0 >= 0 ) && ( lv1 >= 0 ) ) 02551 { 02552 adjents.push_back( cell_id ); 02553 if( leids != NULL ) leids->push_back( lConnMap3D[index].lookup_leids[lv0][lv1] ); 02554 02555 if( adj_orients != NULL ) 02556 { 02557 int cur_leid = lConnMap3D[index].lookup_leids[lv0][lv1]; 02558 int id1 = lConnMap3D[index].e2v[cur_leid][0]; 02559 int id2 = lConnMap3D[index].e2v[cur_leid][1]; 02560 if( ( v_start == conn[id1] ) && ( v_end == conn[id2] ) ) 02561 adj_orients->push_back( 1 ); 02562 else if( ( v_start == conn[id2] ) && ( v_end == conn[id1] ) ) 02563 adj_orients->push_back( 0 ); 02564 } 02565 02566 for( int i = 0; i < qsize; i++ ) 02567 cellq[i] = 0; 02568 02569 break; 02570 } 02571 02572 // push back new found unchecked incident tets of v_start 02573 int cidx = ID_FROM_HANDLE( cell_id ) - 1; 02574 int nhf_thisv = lConnMap3D[index].v2hf_num[lv]; 02575 02576 for( int i = 0; i < nhf_thisv; i++ ) 02577 { 02578 int ind = lConnMap3D[index].v2hf[lv][i]; 02579 HFacet hf = sibhfs[nfpc * cidx + ind]; 02580 EntityHandle ngb = fid_from_halfacet( hf, ctype ); 02581 02582 if( ngb ) 02583 { 02584 bool found_ent = find_match_in_array( ngb, &cellq[0], qsize - 1 ); 02585 02586 if( !found_ent ) 02587 { 02588 cellq[qsize] = ngb; 02589 qsize += 1; 02590 } 02591 } 02592 } 02593 } 02594 02595 for( int i = 0; i < qsize; i++ ) 02596 cellq[i] = 0; 02597 } 02598 02599 return MB_SUCCESS; 02600 } 02601 02602 ErrorCode HalfFacetRep::get_up_adjacencies_face_3d( EntityHandle fid, 02603 std::vector< EntityHandle >& adjents, 02604 std::vector< int >* lfids ) 02605 { 02606 ErrorCode error; 02607 02608 EntityHandle cid = 0; 02609 int lid = 0; 02610 bool found = find_matching_halfface( fid, &cid, &lid ); 02611 02612 if( found ) 02613 { 02614 error = get_up_adjacencies_face_3d( cid, lid, adjents, lfids );MB_CHK_ERR( error ); 02615 } 02616 02617 return MB_SUCCESS; 02618 } 02619 02620 ErrorCode HalfFacetRep::get_up_adjacencies_face_3d( EntityHandle cid, 02621 int lfid, 02622 std::vector< EntityHandle >& adjents, 02623 std::vector< int >* lfids ) 02624 { 02625 02626 EntityHandle start_cell = *_cells.begin(); 02627 EntityType ctype = mb->type_from_handle( start_cell ); 02628 int index = get_index_in_lmap( start_cell ); 02629 int nfpc = lConnMap3D[index].num_faces_in_cell; 02630 02631 adjents.reserve( 4 ); 02632 adjents.push_back( cid ); 02633 02634 if( lfids != NULL ) 02635 { 02636 lfids->reserve( 4 ); 02637 lfids->push_back( lfid ); 02638 } 02639 02640 int cidx = ID_FROM_HANDLE( cid ) - 1; 02641 HFacet hf = sibhfs[nfpc * cidx + lfid]; 02642 EntityHandle sibcid = fid_from_halfacet( hf, ctype ); 02643 int siblid = lid_from_halffacet( hf ); 02644 02645 if( sibcid != 0 ) 02646 { 02647 adjents.push_back( sibcid ); 02648 if( lfids != NULL ) lfids->push_back( siblid ); 02649 } 02650 02651 return MB_SUCCESS; 02652 } 02653 02654 bool HalfFacetRep::find_matching_implicit_edge_in_cell( EntityHandle eid, 02655 std::vector< EntityHandle >& cid, 02656 std::vector< int >& leid ) 02657 { 02658 ErrorCode error; 02659 EntityType ctype = mb->type_from_handle( *_cells.begin() ); 02660 EntityHandle start_cell = *_cells.begin(); 02661 int index = get_index_in_lmap( start_cell ); 02662 int nvpc = lConnMap3D[index].num_verts_in_cell; 02663 int nfpc = lConnMap3D[index].num_faces_in_cell; 02664 02665 // Find the edge vertices 02666 const EntityHandle* econn; 02667 int num_conn = 0; 02668 error = mb->get_connectivity( eid, econn, num_conn, true );MB_CHK_ERR( error ); 02669 02670 EntityHandle v_start = econn[0], v_end = econn[1]; 02671 int v1idx = ID_FROM_HANDLE( v_start ) - 1; 02672 int v2idx = ID_FROM_HANDLE( v_end ) - 1; 02673 02674 // Find an incident cell to v_start 02675 std::vector< EntityHandle > start_cells; 02676 HFacet hf1 = v2hf[v1idx]; 02677 HFacet hf2 = v2hf[v2idx]; 02678 02679 int ncomps1 = 0, ncomps2 = 0, ncomp; 02680 if( hf1 == 0 && !v2hfs.empty() ) 02681 { 02682 std::pair< std::multimap< EntityHandle, HFacet >::iterator, std::multimap< EntityHandle, HFacet >::iterator > 02683 it_hes; 02684 it_hes = v2hfs.equal_range( v_start ); 02685 02686 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 02687 { 02688 start_cells.push_back( fid_from_halfacet( it->second, ctype ) ); 02689 ncomps1 += 1; 02690 } 02691 } 02692 else if( hf1 != 0 ) 02693 { 02694 start_cells.push_back( fid_from_halfacet( hf1, ctype ) ); 02695 ncomps1 += 1; 02696 } 02697 02698 if( hf2 == 0 && !v2hfs.empty() ) 02699 { 02700 std::pair< std::multimap< EntityHandle, HFacet >::iterator, std::multimap< EntityHandle, HFacet >::iterator > 02701 it_hes; 02702 it_hes = v2hfs.equal_range( v_end ); 02703 02704 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 02705 { 02706 start_cells.push_back( fid_from_halfacet( it->second, ctype ) ); 02707 ncomps2 += 1; 02708 } 02709 } 02710 else if( hf2 != 0 ) 02711 { 02712 start_cells.push_back( fid_from_halfacet( hf2, ctype ) ); 02713 ncomps2 += 1; 02714 } 02715 02716 ncomp = std::min( ncomps1, ncomps2 ); 02717 02718 bool found = false; 02719 if( start_cells.empty() ) return found; 02720 02721 for( int i = 0; i < (int)start_cells.size(); i++ ) 02722 cellq[i] = start_cells[i]; 02723 02724 int qsize = start_cells.size(); 02725 int num_qvals = 0; 02726 02727 while( num_qvals < qsize ) 02728 { 02729 EntityHandle cell_id = cellq[num_qvals]; 02730 num_qvals += 1; 02731 02732 const EntityHandle* conn; 02733 error = mb->get_connectivity( cell_id, conn, nvpc, true );MB_CHK_ERR( error ); 02734 02735 int lv0 = -1, lv1 = -1, lv = -1; 02736 02737 // locate v_origin in poped out tet, check if v_end is in 02738 for( int i = 0; i < nvpc; i++ ) 02739 { 02740 if( v_start == conn[i] ) 02741 { 02742 lv0 = i; 02743 lv = lv0; 02744 } 02745 else if( v_end == conn[i] ) 02746 { 02747 lv1 = i; 02748 lv = lv1; 02749 } 02750 } 02751 02752 if( ( lv0 >= 0 ) && ( lv1 >= 0 ) ) 02753 { 02754 found = true; 02755 cid.push_back( cell_id ); 02756 leid.push_back( lConnMap3D[index].lookup_leids[lv0][lv1] ); 02757 02758 if( (int)cid.size() == ncomp ) break; 02759 } 02760 02761 // push back new found unchecked incident tets of v_start 02762 int cidx = ID_FROM_HANDLE( cell_id ) - 1; 02763 int nhf_thisv = lConnMap3D[index].v2hf_num[lv]; 02764 if( lv < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex " ); 02765 for( int i = 0; i < nhf_thisv; i++ ) 02766 { 02767 int ind = lConnMap3D[index].v2hf[lv][i]; 02768 HFacet hf = sibhfs[nfpc * cidx + ind]; 02769 EntityHandle ngb = fid_from_halfacet( hf, ctype ); 02770 02771 if( ngb ) 02772 { 02773 bool found_ent = find_match_in_array( ngb, &cellq[0], qsize - 1 ); 02774 02775 if( !found_ent ) 02776 { 02777 cellq[qsize] = ngb; 02778 qsize += 1; 02779 } 02780 } 02781 } 02782 } 02783 02784 for( int i = 0; i < qsize; i++ ) 02785 cellq[i] = 0; 02786 02787 return found; 02788 } 02789 02790 bool HalfFacetRep::find_matching_halfface( EntityHandle fid, EntityHandle* cid, int* lid ) 02791 { 02792 ErrorCode error; 02793 EntityHandle start_cell = *_cells.begin(); 02794 EntityType ctype = mb->type_from_handle( start_cell ); 02795 int index = get_index_in_lmap( start_cell ); 02796 int nvpc = lConnMap3D[index].num_verts_in_cell; 02797 int nfpc = lConnMap3D[index].num_faces_in_cell; 02798 EntityType ftype = mb->type_from_handle( fid ); 02799 int nvF = lConnMap2D[ftype - 2].num_verts_in_face; 02800 02801 const EntityHandle* fid_verts; 02802 error = mb->get_connectivity( fid, fid_verts, nvF, true );MB_CHK_ERR( error ); 02803 02804 std::vector< EntityHandle > start_cells; 02805 int vidx, locfv0 = -1; 02806 HFacet hf = 0; 02807 02808 for( int i = 0; i < nvF; i++ ) 02809 { 02810 vidx = ID_FROM_HANDLE( fid_verts[i] ) - 1; 02811 hf = v2hf[vidx]; 02812 if( hf != 0 ) 02813 { 02814 start_cells.push_back( fid_from_halfacet( hf, ctype ) ); 02815 locfv0 = i; 02816 break; 02817 } 02818 else if( hf == 0 && v2hfs.find( fid_verts[i] ) != v2hfs.end() ) 02819 { 02820 std::pair< std::multimap< EntityHandle, HFacet >::iterator, 02821 std::multimap< EntityHandle, HFacet >::iterator > 02822 it_hfs; 02823 it_hfs = v2hfs.equal_range( fid_verts[i] ); 02824 02825 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hfs.first; it != it_hfs.second; ++it ) 02826 { 02827 start_cells.push_back( fid_from_halfacet( it->second, ctype ) ); 02828 } 02829 locfv0 = i; 02830 break; 02831 } 02832 } 02833 02834 if( start_cells.empty() ) return false; 02835 02836 EntityHandle cur_cid; 02837 bool found = false; 02838 02839 int Stksize = 0, count = -1; 02840 02841 for( int i = 0; i < (int)start_cells.size(); i++ ) 02842 Stkcells[i] = start_cells[i]; 02843 02844 Stksize = start_cells.size() - 1; 02845 02846 while( Stksize >= 0 ) 02847 { 02848 cur_cid = Stkcells[Stksize]; 02849 Stksize -= 1; 02850 count += 1; 02851 trackcells[count] = cur_cid; 02852 02853 const EntityHandle* conn; 02854 error = mb->get_connectivity( cur_cid, conn, nvpc, true );MB_CHK_ERR( error ); 02855 02856 int lv[4] = { -1, -1, -1, -1 }; 02857 int cnt = 0; 02858 for( int i = 0; i < nvpc; i++ ) 02859 { 02860 for( int j = 0; j < nvF; j++ ) 02861 if( conn[i] == fid_verts[j] ) 02862 { 02863 lv[j] = i; 02864 cnt += 1; 02865 } 02866 } 02867 if( cnt == nvF ) // All face verts are part of the cell 02868 { 02869 found = true; 02870 int nhf_thisv = lConnMap3D[index].v2hf_num[lv[locfv0]]; 02871 int lfid = -1; 02872 for( int i = 0; i < nhf_thisv; ++i ) 02873 { 02874 lfid = lConnMap3D[index].v2hf[lv[locfv0]][i]; 02875 int lcnt = 0; 02876 for( int j = 0; j < nvF; ++j ) 02877 { 02878 for( int k = 0; k < nvF; ++k ) 02879 { 02880 if( lv[k] == lConnMap3D[index].hf2v[lfid][j] ) lcnt += 1; 02881 } 02882 } 02883 if( lcnt == nvF ) break; 02884 } 02885 cid[0] = cur_cid; 02886 lid[0] = lfid; 02887 02888 break; 02889 } 02890 else 02891 { 02892 // Add other cells that are incident on fid_verts[0] 02893 if( locfv0 < 0 || lv[locfv0] < 0 ) MB_SET_ERR( MB_FAILURE, "did not find local vertex " ); 02894 int nhf_thisv = lConnMap3D[index].v2hf_num[lv[locfv0]]; 02895 int cidx = ID_FROM_HANDLE( cur_cid ) - 1; 02896 02897 // Add new cells into the stack 02898 EntityHandle ngb; 02899 for( int i = 0; i < nhf_thisv; ++i ) 02900 { 02901 int ind = lConnMap3D[index].v2hf[lv[locfv0]][i]; 02902 hf = sibhfs[nfpc * cidx + ind]; 02903 ngb = fid_from_halfacet( hf, ctype ); 02904 02905 if( ngb ) 02906 { 02907 02908 bool found_ent = find_match_in_array( ngb, trackcells, count ); 02909 02910 if( !found_ent ) 02911 { 02912 Stksize += 1; 02913 Stkcells[Stksize] = ngb; 02914 } 02915 } 02916 } 02917 } 02918 } 02919 02920 // Change the visited faces to false 02921 for( int i = 0; i < Stksize; i++ ) 02922 Stkcells[i] = 0; 02923 02924 for( int i = 0; i <= count; i++ ) 02925 trackcells[i] = 0; 02926 02927 return found; 02928 } 02929 02930 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 02931 ErrorCode HalfFacetRep::get_neighbor_adjacencies_3d( EntityHandle cid, std::vector< EntityHandle >& adjents ) 02932 { 02933 adjents.reserve( 20 ); 02934 EntityType ctype = mb->type_from_handle( cid ); 02935 int index = get_index_in_lmap( cid ); 02936 int nfpc = lConnMap3D[index].num_faces_in_cell; 02937 int cidx = ID_FROM_HANDLE( cid ) - 1; 02938 02939 if( cid != 0 ) 02940 { 02941 for( int lfid = 0; lfid < nfpc; ++lfid ) 02942 { 02943 HFacet hf = sibhfs[nfpc * cidx + lfid]; 02944 EntityHandle sibcid = fid_from_halfacet( hf, ctype ); 02945 if( sibcid != 0 ) adjents.push_back( sibcid ); 02946 } 02947 } 02948 02949 return MB_SUCCESS; 02950 } 02951 02952 ///////////////////////////////////////////////////////////////////////////////////////////////// 02953 ErrorCode HalfFacetRep::get_down_adjacencies_edg_3d( EntityHandle cid, std::vector< EntityHandle >& adjents ) 02954 { 02955 // TODO: Try intersection without using std templates 02956 // Returns explicit edges, if any, of the face 02957 ErrorCode error; 02958 adjents.reserve( 20 ); 02959 int index = get_index_in_lmap( cid ); 02960 int nvpc = lConnMap3D[index].num_verts_in_cell; 02961 02962 const EntityHandle* conn; 02963 error = mb->get_connectivity( cid, conn, nvpc, true );MB_CHK_ERR( error ); 02964 02965 // Gather all the incident edges on each vertex of the face 02966 int ns = lConnMap3D[index].search_everts[0]; 02967 std::vector< EntityHandle > temp; 02968 for( int i = 0; i < ns; i++ ) 02969 { 02970 temp.clear(); 02971 int lv0 = lConnMap3D[index].search_everts[i + 1]; 02972 error = get_up_adjacencies_1d( conn[lv0], temp );MB_CHK_ERR( error ); 02973 02974 int nle = lConnMap3D[index].v2le[i][0]; 02975 int count = 0; 02976 for( int j = 0; j < (int)temp.size(); j++ ) 02977 { 02978 const EntityHandle* econn; 02979 int nvpe = 0; 02980 error = mb->get_connectivity( temp[j], econn, nvpe, true );MB_CHK_ERR( error ); 02981 02982 for( int k = 0; k < nle; k++ ) 02983 { 02984 int lv1 = lConnMap3D[index].v2le[i][k + 1]; 02985 if( ( ( econn[0] == conn[lv0] ) && ( econn[1] == conn[lv1] ) ) || 02986 ( ( econn[1] == conn[lv0] ) && ( econn[0] == conn[lv1] ) ) ) 02987 { 02988 adjents.push_back( temp[j] ); 02989 count += 1; 02990 } 02991 } 02992 if( count == nle ) break; 02993 } 02994 } 02995 return MB_SUCCESS; 02996 } 02997 02998 ErrorCode HalfFacetRep::get_down_adjacencies_face_3d( EntityHandle cid, std::vector< EntityHandle >& adjents ) 02999 { 03000 // Returns explicit face, if any of the cell 03001 ErrorCode error; 03002 adjents.reserve( 10 ); 03003 int index = get_index_in_lmap( cid ); 03004 int nvpc = lConnMap3D[index].num_verts_in_cell; 03005 int nfpc = lConnMap3D[index].num_faces_in_cell; 03006 03007 // Get the connectivity of the input cell 03008 const EntityHandle* conn; 03009 error = mb->get_connectivity( cid, conn, nvpc, true );MB_CHK_ERR( error ); 03010 03011 // Collect all the half-faces of the cell 03012 EntityHandle half_faces[6][4]; 03013 for( int i = 0; i < nfpc; i++ ) 03014 { 03015 int nvf = lConnMap3D[index].hf2v_num[i]; 03016 for( int j = 0; j < nvf; j++ ) 03017 { 03018 int ind = lConnMap3D[index].hf2v[i][j]; 03019 half_faces[i][j] = conn[ind]; 03020 } 03021 } 03022 03023 // Add two vertices for which the upward adjacencies are computed 03024 int search_verts[2]; 03025 search_verts[0] = lConnMap3D[index].search_fverts[0]; 03026 search_verts[1] = lConnMap3D[index].search_fverts[1]; 03027 03028 std::vector< EntityHandle > temp; 03029 temp.reserve( 20 ); 03030 for( int i = 0; i < 2; i++ ) 03031 { 03032 // Get the incident faces on the local vertex 03033 int lv = search_verts[i]; 03034 temp.clear(); 03035 error = get_up_adjacencies_vert_2d( conn[lv], temp );MB_CHK_ERR( error ); 03036 03037 if( temp.size() == 0 ) continue; 03038 03039 // Get the half-faces incident on the local vertex and match it with the obtained faces 03040 int nhfthisv = lConnMap3D[index].v2hf_num[lv]; 03041 for( int k = 0; k < (int)temp.size(); k++ ) 03042 { 03043 const EntityHandle* fid_verts; 03044 int fsize = 0; 03045 error = mb->get_connectivity( temp[k], fid_verts, fsize, true );MB_CHK_ERR( error ); 03046 03047 for( int j = 0; j < nhfthisv; j++ ) 03048 { 03049 // Collect all the vertices of this half-face 03050 int idx = lConnMap3D[index].v2hf[lv][j]; 03051 int nvF = lConnMap3D[index].hf2v_num[idx]; 03052 03053 if( fsize != nvF ) continue; 03054 03055 int direct, offset; 03056 bool they_match = CN::ConnectivityMatch( &half_faces[idx][0], &fid_verts[0], nvF, direct, offset ); 03057 03058 if( they_match ) 03059 { 03060 bool found = false; 03061 for( int p = 0; p < (int)adjents.size(); p++ ) 03062 { 03063 if( adjents[p] == temp[k] ) 03064 { 03065 found = true; 03066 break; 03067 } 03068 } 03069 if( !found ) adjents.push_back( temp[k] ); 03070 } 03071 } 03072 } 03073 } 03074 03075 return MB_SUCCESS; 03076 } 03077 //////////////////////////////////////////////////////////////////////////////// 03078 ErrorCode HalfFacetRep::find_total_edges_faces_3d( const Range& cells, int* nedges, int* nfaces ) 03079 { 03080 ErrorCode error; 03081 int index = get_index_in_lmap( *cells.begin() ); 03082 int nepc = lConnMap3D[index].num_edges_in_cell; 03083 int nfpc = lConnMap3D[index].num_faces_in_cell; 03084 int ncells = cells.size(); 03085 int total_edges = nepc * ncells; 03086 int total_faces = nfpc * ncells; 03087 03088 std::vector< int > trackE( total_edges, 0 ); 03089 std::vector< int > trackF( total_faces, 0 ); 03090 03091 std::vector< EntityHandle > inc_cids, sib_cids; 03092 std::vector< int > inc_leids, sib_lfids; 03093 03094 for( Range::iterator it = cells.begin(); it != cells.end(); ++it ) 03095 { 03096 // Count edges 03097 for( int i = 0; i < nepc; i++ ) 03098 { 03099 inc_cids.clear(); 03100 inc_leids.clear(); 03101 03102 int id = nepc * ( cells.index( *it ) ) + i; 03103 if( !trackE[id] ) 03104 { 03105 error = get_up_adjacencies_edg_3d( *it, i, inc_cids, &inc_leids );MB_CHK_ERR( error ); 03106 03107 total_edges -= inc_cids.size() - 1; 03108 for( int j = 0; j < (int)inc_cids.size(); j++ ) 03109 trackE[nepc * ( cells.index( inc_cids[j] ) ) + inc_leids[j]] = 1; 03110 } 03111 } 03112 03113 // Count faces 03114 for( int i = 0; i < nfpc; i++ ) 03115 { 03116 sib_cids.clear(); 03117 sib_lfids.clear(); 03118 03119 int id = nfpc * ( cells.index( *it ) ) + i; 03120 if( !trackF[id] ) 03121 { 03122 error = get_up_adjacencies_face_3d( *it, i, sib_cids, &sib_lfids );MB_CHK_ERR( error ); 03123 03124 if( sib_cids.size() == 1 ) continue; 03125 03126 total_faces -= sib_cids.size() - 1; 03127 trackF[nfpc * ( cells.index( sib_cids[1] ) ) + sib_lfids[1]] = 1; 03128 } 03129 } 03130 } 03131 03132 nedges[0] = total_edges; 03133 nfaces[0] = total_faces; 03134 03135 return MB_SUCCESS; 03136 } 03137 03138 bool HalfFacetRep::find_match_in_array( EntityHandle ent, 03139 EntityHandle* ent_list, 03140 int count, 03141 bool get_index, 03142 int* index ) 03143 { 03144 bool found = false; 03145 for( int i = 0; i <= count; i++ ) 03146 { 03147 if( ent == ent_list[i] ) 03148 { 03149 found = true; 03150 if( get_index ) *index = i; 03151 break; 03152 } 03153 } 03154 03155 return found; 03156 } 03157 03158 ErrorCode HalfFacetRep::get_half_facet_in_comp( EntityHandle cid, 03159 int leid, 03160 std::vector< EntityHandle >& ents, 03161 std::vector< int >& lids, 03162 std::vector< int >& lfids ) 03163 { 03164 ErrorCode error; 03165 ents.clear(); 03166 lids.clear(); 03167 EntityType ctype = mb->type_from_handle( cid ); 03168 int index = get_index_in_lmap( *_cells.begin() ); 03169 int nfpc = lConnMap3D[index].num_faces_in_cell; 03170 int nvpc = lConnMap3D[index].num_verts_in_cell; 03171 03172 // Get all incident cells 03173 std::vector< EntityHandle > adjents; 03174 std::vector< int > adjlids; 03175 error = get_up_adjacencies_edg_3d( cid, leid, adjents, &adjlids );MB_CHK_ERR( error ); 03176 03177 // Get the end vertices of the edge <cid,leid> 03178 const EntityHandle* econn; 03179 error = mb->get_connectivity( cid, econn, nvpc, true );MB_CHK_ERR( error ); 03180 int id = lConnMap3D[index].e2v[leid][0]; 03181 EntityHandle vstart = econn[id]; 03182 id = lConnMap3D[index].e2v[leid][1]; 03183 EntityHandle vend = econn[id]; 03184 03185 std::vector< int > mark( adjents.size(), 0 ); 03186 int count = 0; 03187 03188 for( int k = 0; k < (int)adjents.size(); k++ ) 03189 { 03190 03191 if( mark[k] != 0 ) continue; 03192 03193 count += 1; 03194 mark[k] = count; 03195 03196 // Loop over each half-face incident on this local edge 03197 for( int i = 0; i < 2; i++ ) 03198 { 03199 EntityHandle cur_cell = adjents[k]; 03200 int cur_leid = adjlids[k]; 03201 03202 int lface = i; 03203 03204 while( true ) 03205 { 03206 int cidx = ID_FROM_HANDLE( cur_cell ) - 1; 03207 int lfid = lConnMap3D[index].e2hf[cur_leid][lface]; 03208 03209 HFacet hf = sibhfs[nfpc * cidx + lfid]; 03210 cur_cell = fid_from_halfacet( hf, ctype ); 03211 lfid = lid_from_halffacet( hf ); 03212 03213 // Check if loop reached starting cell or a boundary 03214 if( ( cur_cell == adjents[k] ) || ( cur_cell == 0 ) ) break; 03215 03216 const EntityHandle* sib_conn; 03217 error = mb->get_connectivity( cur_cell, sib_conn, nvpc, true );MB_CHK_ERR( error ); 03218 03219 // Find the local edge id wrt to sibhf 03220 int nv_curF = lConnMap3D[index].hf2v_num[lfid]; 03221 int lv0 = -1, lv1 = -1, idx = -1; 03222 for( int j = 0; j < nv_curF; j++ ) 03223 { 03224 idx = lConnMap3D[index].hf2v[lfid][j]; 03225 if( vstart == sib_conn[idx] ) lv0 = idx; 03226 if( vend == sib_conn[idx] ) lv1 = idx; 03227 } 03228 03229 assert( ( lv0 >= 0 ) && ( lv1 >= 0 ) ); 03230 cur_leid = lConnMap3D[index].lookup_leids[lv0][lv1]; 03231 03232 int chk_lfid = lConnMap3D[index].e2hf[cur_leid][0]; 03233 03234 if( lfid == chk_lfid ) 03235 lface = 1; 03236 else 03237 lface = 0; 03238 03239 int ind = std::find( adjents.begin(), adjents.end(), cur_cell ) - adjents.begin(); 03240 mark[ind] = count; 03241 } 03242 03243 // Loop back 03244 if( cur_cell != 0 ) break; 03245 } 03246 } 03247 03248 // Loop over again to find cells on the boundary 03249 for( int c = 0; c < count; c++ ) 03250 { 03251 for( int i = 0; i < (int)adjents.size(); i++ ) 03252 { 03253 if( mark[i] == c + 1 ) 03254 { 03255 int cidx = ID_FROM_HANDLE( adjents[i] ) - 1; 03256 for( int j = 0; j < nfpc; j++ ) 03257 { 03258 HFacet hf = sibhfs[nfpc * cidx + j]; 03259 EntityHandle cell = fid_from_halfacet( hf, ctype ); 03260 if( cell == 0 ) 03261 { 03262 ents.push_back( adjents[i] ); 03263 lids.push_back( adjlids[i] ); 03264 lfids.push_back( j ); 03265 break; 03266 } 03267 } 03268 } 03269 } 03270 } 03271 03272 return MB_SUCCESS; 03273 } 03274 03275 /////////////////////////////////////////////////////////////////////////////////////////// 03276 ErrorCode HalfFacetRep::resize_hf_maps( EntityHandle start_vert, 03277 int nverts, 03278 EntityHandle start_edge, 03279 int nedges, 03280 EntityHandle start_face, 03281 int nfaces, 03282 EntityHandle start_cell, 03283 int ncells ) 03284 { 03285 int nwsz = 0, insz = 0; 03286 if( nedges ) 03287 { 03288 if( ID_FROM_HANDLE( ( *( _edges.end() - 1 ) + 1 ) ) != ID_FROM_HANDLE( start_edge ) ) 03289 nwsz = ( ID_FROM_HANDLE( start_edge ) - ID_FROM_HANDLE( *_edges.end() ) + nedges ) * 2; 03290 else 03291 nwsz = nedges * 2; 03292 insz = sibhvs.size(); 03293 sibhvs.resize( insz + nwsz, 0 ); 03294 03295 if( v2hv.empty() ) 03296 { 03297 if( ( !v2he.empty() ) ) 03298 insz = v2he.size(); 03299 else if( ( !v2hf.empty() ) ) 03300 insz = v2hf.size(); 03301 else 03302 MB_SET_ERR( MB_FAILURE, "Trying to resize ahf maps for a mesh with no edges, faces and cells" ); 03303 } 03304 else 03305 insz = v2hv.size(); 03306 03307 if( ID_FROM_HANDLE( *( _verts.end() - 1 ) + 1 ) != ID_FROM_HANDLE( start_vert ) ) 03308 nwsz = ID_FROM_HANDLE( start_vert ) - ID_FROM_HANDLE( *_verts.end() ) + nverts; 03309 else 03310 nwsz = nverts; 03311 v2hv.resize( insz + nwsz, 0 ); 03312 } 03313 03314 if( nfaces ) 03315 { 03316 EntityType ftype = mb->type_from_handle( *_faces.begin() ); 03317 int nepf = lConnMap2D[ftype - 2].num_verts_in_face; 03318 03319 if( ID_FROM_HANDLE( ( *( _faces.end() - 1 ) + 1 ) ) != ID_FROM_HANDLE( start_face ) ) 03320 nwsz = ( ID_FROM_HANDLE( start_face ) - ID_FROM_HANDLE( *_faces.end() ) + nfaces ) * nepf; 03321 else 03322 nwsz = nfaces * nepf; 03323 insz = sibhes.size(); 03324 sibhes.resize( insz + nwsz, 0 ); 03325 03326 if( ID_FROM_HANDLE( *( _verts.end() - 1 ) + 1 ) != ID_FROM_HANDLE( start_vert ) ) 03327 nwsz = ID_FROM_HANDLE( start_vert ) - ID_FROM_HANDLE( *_verts.end() ) + nverts; 03328 else 03329 nwsz = nverts; 03330 insz = v2he.size(); 03331 v2he.resize( insz + nwsz, 0 ); 03332 } 03333 03334 if( ncells ) 03335 { 03336 int index = get_index_in_lmap( *_cells.begin() ); 03337 int nfpc = lConnMap3D[index].num_faces_in_cell; 03338 03339 if( ID_FROM_HANDLE( ( *( _cells.end() - 1 ) + 1 ) ) != ID_FROM_HANDLE( start_cell ) ) 03340 nwsz = ( ID_FROM_HANDLE( start_cell ) - ID_FROM_HANDLE( *_cells.end() ) + ncells ) * nfpc; 03341 else 03342 nwsz = ncells * nfpc; 03343 insz = sibhfs.size(); 03344 sibhfs.resize( insz + nwsz, 0 ); 03345 03346 if( ID_FROM_HANDLE( *( _verts.end() - 1 ) + 1 ) != ID_FROM_HANDLE( start_vert ) ) 03347 nwsz = ID_FROM_HANDLE( start_vert ) - ID_FROM_HANDLE( *_verts.end() ) + nverts; 03348 else 03349 nwsz = nverts; 03350 insz = v2hf.size(); 03351 v2hf.resize( insz + nwsz, 0 ); 03352 } 03353 03354 return MB_SUCCESS; 03355 } 03356 03357 bool HalfFacetRep::check_nonmanifold_vertices( EntityType type, EntityHandle vid ) 03358 { 03359 bool status = false; 03360 if( type == MBTRI || type == MBQUAD ) 03361 { 03362 HFacet hf = v2he[ID_FROM_HANDLE( vid ) - 1]; 03363 if( hf == 0 && ( v2hes.find( vid ) != v2hes.end() ) ) status = true; 03364 } 03365 else if( type == MBTET || type == MBHEX ) 03366 { 03367 HFacet hf = v2hf[ID_FROM_HANDLE( vid ) - 1]; 03368 if( hf == 0 && ( v2hfs.find( vid ) != v2hfs.end() ) ) status = true; 03369 } 03370 else 03371 MB_SET_ERR( MB_FAILURE, "Requesting non-manifold vertex checks for either (1) 1D mesh or " 03372 "(2) not-implemented entity types" ); 03373 03374 return status; 03375 } 03376 03377 ErrorCode HalfFacetRep::get_sibling_map( EntityType type, 03378 EntityHandle ent, 03379 EntityHandle* sib_entids, 03380 int* sib_lids, 03381 int num_halffacets ) 03382 { 03383 03384 if( type == MBEDGE ) 03385 { 03386 if( num_halffacets != 2 ) MB_SET_ERR( MB_FAILURE, "Incorrect number of halfvertices." ); 03387 03388 int eidx = ID_FROM_HANDLE( ent ) - 1; 03389 for( int i = 0; i < 2; i++ ) 03390 { 03391 HFacet hf = sibhvs[2 * eidx + i]; 03392 sib_entids[i] = fid_from_halfacet( hf, MBEDGE ); 03393 sib_lids[i] = lid_from_halffacet( hf ); 03394 } 03395 } 03396 else if( type == MBTRI || type == MBQUAD ) 03397 { 03398 int nepf = lConnMap2D[type - 2].num_verts_in_face; 03399 03400 if( num_halffacets != nepf ) MB_SET_ERR( MB_FAILURE, "Incorrect number of halfedges." ); 03401 03402 int fidx = ID_FROM_HANDLE( ent ) - 1; 03403 for( int i = 0; i < nepf; i++ ) 03404 { 03405 HFacet hf = sibhes[nepf * fidx + i]; 03406 sib_entids[i] = fid_from_halfacet( hf, type ); 03407 sib_lids[i] = lid_from_halffacet( hf ); 03408 } 03409 } 03410 else 03411 { 03412 int idx = get_index_in_lmap( *_cells.begin() ); 03413 int nfpc = lConnMap3D[idx].num_faces_in_cell; 03414 03415 if( num_halffacets != nfpc ) MB_SET_ERR( MB_FAILURE, "Incorrect number of halffaces." ); 03416 03417 int cidx = ID_FROM_HANDLE( ent ) - 1; 03418 for( int i = 0; i < nfpc; i++ ) 03419 { 03420 HFacet hf = sibhfs[nfpc * cidx + i]; 03421 sib_entids[i] = fid_from_halfacet( hf, type ); 03422 sib_lids[i] = lid_from_halffacet( hf ); 03423 } 03424 } 03425 return MB_SUCCESS; 03426 } 03427 03428 ErrorCode HalfFacetRep::get_sibling_map( EntityType type, 03429 EntityHandle ent, 03430 int lid, 03431 EntityHandle& sib_entid, 03432 int& sib_lid ) 03433 { 03434 03435 if( type == MBEDGE ) 03436 { 03437 int eidx = ID_FROM_HANDLE( ent ) - 1; 03438 HFacet hf = sibhvs[2 * eidx + lid]; 03439 sib_entid = fid_from_halfacet( hf, MBEDGE ); 03440 sib_lid = lid_from_halffacet( hf ); 03441 } 03442 else if( type == MBTRI || type == MBQUAD ) 03443 { 03444 int nepf = lConnMap2D[type - 2].num_verts_in_face; 03445 int fidx = ID_FROM_HANDLE( ent ) - 1; 03446 HFacet hf = sibhes[nepf * fidx + lid]; 03447 sib_entid = fid_from_halfacet( hf, type ); 03448 sib_lid = lid_from_halffacet( hf ); 03449 } 03450 else 03451 { 03452 int idx = get_index_in_lmap( *_cells.begin() ); 03453 int nfpc = lConnMap3D[idx].num_faces_in_cell; 03454 int cidx = ID_FROM_HANDLE( ent ) - 1; 03455 HFacet hf = sibhfs[nfpc * cidx + lid]; 03456 sib_entid = fid_from_halfacet( hf, type ); 03457 sib_lid = lid_from_halffacet( hf ); 03458 } 03459 return MB_SUCCESS; 03460 } 03461 03462 ErrorCode HalfFacetRep::set_sibling_map( EntityType type, 03463 EntityHandle ent, 03464 EntityHandle* set_entids, 03465 int* set_lids, 03466 int num_halffacets ) 03467 { 03468 03469 if( type == MBEDGE ) 03470 { 03471 if( num_halffacets != 2 ) MB_SET_ERR( MB_FAILURE, "Incorrect number of halfvertices" ); 03472 03473 int eidx = ID_FROM_HANDLE( ent ) - 1; 03474 for( int i = 0; i < 2; i++ ) 03475 { 03476 sibhvs[2 * eidx + i] = create_halffacet( set_entids[i], set_lids[i] ); 03477 } 03478 } 03479 else if( type == MBTRI || type == MBQUAD ) 03480 { 03481 int nepf = lConnMap2D[type - 2].num_verts_in_face; 03482 if( num_halffacets != nepf ) MB_SET_ERR( MB_FAILURE, "Incorrect number of halfedges." ); 03483 03484 int fidx = ID_FROM_HANDLE( ent ) - 1; 03485 for( int i = 0; i < nepf; i++ ) 03486 { 03487 sibhes[nepf * fidx + i] = create_halffacet( set_entids[i], set_lids[i] ); 03488 } 03489 } 03490 else 03491 { 03492 int idx = get_index_in_lmap( *_cells.begin() ); 03493 int nfpc = lConnMap3D[idx].num_faces_in_cell; 03494 if( num_halffacets != nfpc ) MB_SET_ERR( MB_FAILURE, "Incorrect number of halffaces." ); 03495 03496 int cidx = ID_FROM_HANDLE( ent ) - 1; 03497 for( int i = 0; i < nfpc; i++ ) 03498 { 03499 sibhfs[nfpc * cidx + i] = create_halffacet( set_entids[i], set_lids[i] ); 03500 } 03501 } 03502 03503 return MB_SUCCESS; 03504 } 03505 03506 ErrorCode HalfFacetRep::set_sibling_map( EntityType type, 03507 EntityHandle ent, 03508 int lid, 03509 EntityHandle& set_entid, 03510 int& set_lid ) 03511 { 03512 03513 if( type == MBEDGE ) 03514 { 03515 int eidx = ID_FROM_HANDLE( ent ) - 1; 03516 sibhvs[2 * eidx + lid] = create_halffacet( set_entid, set_lid ); 03517 } 03518 else if( type == MBTRI || type == MBQUAD ) 03519 { 03520 int nepf = lConnMap2D[type - 2].num_verts_in_face; 03521 int fidx = ID_FROM_HANDLE( ent ) - 1; 03522 sibhes[nepf * fidx + lid] = create_halffacet( set_entid, set_lid ); 03523 } 03524 else 03525 { 03526 int idx = get_index_in_lmap( *_cells.begin() ); 03527 int nfpc = lConnMap3D[idx].num_faces_in_cell; 03528 int cidx = ID_FROM_HANDLE( ent ) - 1; 03529 sibhfs[nfpc * cidx + lid] = create_halffacet( set_entid, set_lid ); 03530 } 03531 03532 return MB_SUCCESS; 03533 } 03534 03535 ErrorCode HalfFacetRep::get_incident_map( EntityType type, 03536 EntityHandle vid, 03537 std::vector< EntityHandle >& inci_entid, 03538 std::vector< int >& inci_lid ) 03539 { 03540 inci_entid.clear(); 03541 inci_lid.clear(); 03542 03543 if( type == MBEDGE ) 03544 { 03545 HFacet hf = v2hv[ID_FROM_HANDLE( vid ) - 1]; 03546 inci_entid.push_back( fid_from_halfacet( hf, type ) ); 03547 inci_lid.push_back( lid_from_halffacet( hf ) ); 03548 } 03549 else if( type == MBTRI || type == MBQUAD ) 03550 { 03551 HFacet hf = v2he[ID_FROM_HANDLE( vid ) - 1]; 03552 if( hf == 0 && ( v2hes.find( vid ) != v2hes.end() ) ) 03553 { 03554 std::pair< std::multimap< EntityHandle, HFacet >::iterator, 03555 std::multimap< EntityHandle, HFacet >::iterator > 03556 it_hes; 03557 it_hes = v2hes.equal_range( vid ); 03558 03559 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 03560 { 03561 inci_entid.push_back( fid_from_halfacet( it->second, type ) ); 03562 inci_lid.push_back( lid_from_halffacet( it->second ) ); 03563 } 03564 } 03565 else if( hf != 0 ) 03566 { 03567 inci_entid.push_back( fid_from_halfacet( hf, type ) ); 03568 inci_lid.push_back( lid_from_halffacet( hf ) ); 03569 } 03570 else if( hf == 0 && ( v2hes.find( vid ) == v2hes.end() ) ) 03571 { 03572 inci_entid.push_back( fid_from_halfacet( hf, type ) ); 03573 inci_lid.push_back( lid_from_halffacet( hf ) ); 03574 } 03575 } 03576 else 03577 { 03578 HFacet hf = v2hf[ID_FROM_HANDLE( vid ) - 1]; 03579 if( hf == 0 && ( v2hfs.find( vid ) != v2hfs.end() ) ) 03580 { 03581 std::pair< std::multimap< EntityHandle, HFacet >::iterator, 03582 std::multimap< EntityHandle, HFacet >::iterator > 03583 it_hes; 03584 it_hes = v2hfs.equal_range( vid ); 03585 03586 for( std::multimap< EntityHandle, HFacet >::iterator it = it_hes.first; it != it_hes.second; ++it ) 03587 { 03588 inci_entid.push_back( fid_from_halfacet( it->second, type ) ); 03589 inci_lid.push_back( lid_from_halffacet( it->second ) ); 03590 } 03591 } 03592 else if( hf != 0 ) 03593 { 03594 inci_entid.push_back( fid_from_halfacet( hf, type ) ); 03595 inci_lid.push_back( lid_from_halffacet( hf ) ); 03596 } 03597 else if( hf == 0 && ( v2hfs.find( vid ) == v2hfs.end() ) ) 03598 { 03599 inci_entid.push_back( fid_from_halfacet( hf, type ) ); 03600 inci_lid.push_back( lid_from_halffacet( hf ) ); 03601 } 03602 } 03603 03604 return MB_SUCCESS; 03605 } 03606 03607 ErrorCode HalfFacetRep::set_incident_map( EntityType type, 03608 EntityHandle vid, 03609 std::vector< EntityHandle >& set_entid, 03610 std::vector< int >& set_lid ) 03611 { 03612 if( type == MBEDGE ) 03613 { 03614 v2hv[ID_FROM_HANDLE( vid ) - 1] = create_halffacet( set_entid[0], set_lid[0] ); 03615 } 03616 else if( type == MBTRI || type == MBQUAD ) 03617 { 03618 if( set_entid.size() == 1 ) 03619 v2he[ID_FROM_HANDLE( vid ) - 1] = create_halffacet( set_entid[0], set_lid[0] ); 03620 else 03621 { 03622 HFacet hf = 0; 03623 for( int i = 0; i < (int)set_entid.size(); i++ ) 03624 { 03625 hf = create_halffacet( set_entid[i], set_lid[i] ); 03626 v2hes.insert( std::pair< EntityHandle, HFacet >( vid, hf ) ); 03627 } 03628 } 03629 } 03630 else 03631 { 03632 if( set_entid.size() == 1 ) 03633 v2hf[ID_FROM_HANDLE( vid ) - 1] = create_halffacet( set_entid[0], set_lid[0] ); 03634 else 03635 { 03636 HFacet hf = v2hf[ID_FROM_HANDLE( vid ) - 1]; 03637 if( hf != 0 ) 03638 { 03639 v2hf[ID_FROM_HANDLE( vid ) - 1] = 0; 03640 } 03641 for( int i = 0; i < (int)set_entid.size(); i++ ) 03642 { 03643 hf = create_halffacet( set_entid[i], set_lid[i] ); 03644 v2hfs.insert( std::pair< EntityHandle, HFacet >( vid, hf ) ); 03645 } 03646 } 03647 } 03648 03649 return MB_SUCCESS; 03650 } 03651 03652 ErrorCode HalfFacetRep::get_entity_ranges( Range& verts, Range& edges, Range& faces, Range& cells ) 03653 { 03654 verts = _verts; 03655 edges = _edges; 03656 faces = _faces; 03657 cells = _cells; 03658 return MB_SUCCESS; 03659 } 03660 03661 ErrorCode HalfFacetRep::update_entity_ranges( EntityHandle fileset ) 03662 { 03663 ErrorCode error; 03664 03665 error = mb->get_entities_by_dimension( fileset, 0, _verts, true );MB_CHK_ERR( error ); 03666 03667 error = mb->get_entities_by_dimension( fileset, 1, _edges, true );MB_CHK_ERR( error ); 03668 03669 error = mb->get_entities_by_dimension( fileset, 2, _faces, true );MB_CHK_ERR( error ); 03670 03671 error = mb->get_entities_by_dimension( fileset, 3, _cells, true );MB_CHK_ERR( error ); 03672 03673 return MB_SUCCESS; 03674 } 03675 03676 void HalfFacetRep::get_memory_use( unsigned long long& entity_total, unsigned long long& memory_total ) 03677 { 03678 entity_total = memory_total = 0; 03679 // 1D 03680 if( !v2hv.empty() ) entity_total += v2hv.capacity() * sizeof( HFacet ) + sizeof( v2hv ); 03681 if( !sibhvs.empty() ) entity_total += sibhvs.capacity() * sizeof( HFacet ) + sizeof( sibhvs ); 03682 03683 // 2D 03684 if( !v2he.empty() ) entity_total += v2he.capacity() * sizeof( HFacet ) + sizeof( v2he ); 03685 if( !sibhes.empty() ) entity_total += sibhes.capacity() * sizeof( HFacet ) + sizeof( sibhes ); 03686 03687 // 3D 03688 if( !v2hf.empty() ) entity_total += v2hf.capacity() * sizeof( HFacet ) + sizeof( v2hf ); 03689 if( !sibhfs.empty() ) entity_total += sibhfs.capacity() * sizeof( HFacet ) + sizeof( sibhfs ); 03690 03691 memory_total = entity_total; 03692 } 03693 03694 HFacet HalfFacetRep::create_halffacet( EntityHandle handle, int lid ) 03695 { 03696 EntityID fid = ID_FROM_HANDLE( handle ); 03697 return CREATE_HALFFACET( lid, fid ); 03698 } 03699 03700 EntityHandle HalfFacetRep::fid_from_halfacet( const HFacet facet, EntityType type ) 03701 { 03702 EntityID id = FID_FROM_HALFFACET( facet ); 03703 EntityHandle handle = 0; 03704 if( id == 0 ) return handle; 03705 03706 ErrorCode error = mb->handle_from_id( type, id, handle );MB_CHK_ERR( error ); 03707 return handle; 03708 } 03709 03710 int HalfFacetRep::lid_from_halffacet( const HFacet facet ) 03711 { 03712 if( facet == 0 ) 03713 return 0; 03714 else 03715 return LID_FROM_HALFFACET( facet ); 03716 } 03717 03718 } // namespace moab