LCOV - code coverage report
Current view: top level - src - AEntityFactory.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 496 575 86.3 %
Date: 2020-12-16 07:07:30 Functions: 33 34 97.1 %
Branches: 646 1277 50.6 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
       3                 :            :  * storing and accessing finite element mesh data.
       4                 :            :  *
       5                 :            :  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
       6                 :            :  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
       7                 :            :  * retains certain rights in this software.
       8                 :            :  *
       9                 :            :  * This library is free software; you can redistribute it and/or
      10                 :            :  * modify it under the terms of the GNU Lesser General Public
      11                 :            :  * License as published by the Free Software Foundation; either
      12                 :            :  * version 2.1 of the License, or (at your option) any later version.
      13                 :            :  *
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "AEntityFactory.hpp"
      17                 :            : #include "Internals.hpp"
      18                 :            : #include "moab/Core.hpp"
      19                 :            : #include "moab/Range.hpp"
      20                 :            : #include "moab/Error.hpp"
      21                 :            : #include "moab/CN.hpp"
      22                 :            : #include "moab/MeshTopoUtil.hpp"
      23                 :            : #include "EntitySequence.hpp"
      24                 :            : #include "SequenceData.hpp"
      25                 :            : #include "SequenceManager.hpp"
      26                 :            : #include "RangeSeqIntersectIter.hpp"
      27                 :            : 
      28                 :            : #include <assert.h>
      29                 :            : #include <algorithm>
      30                 :            : #include <set>
      31                 :            : 
      32                 :            : namespace moab
      33                 :            : {
      34                 :            : 
      35                 :     163487 : ErrorCode AEntityFactory::get_vertices( EntityHandle h, const EntityHandle*& vect_out, int& count_out,
      36                 :            :                                         std::vector< EntityHandle >& storage )
      37                 :            : {
      38                 :            :     ErrorCode result;
      39         [ +  + ]:     163487 :     if( MBPOLYHEDRON == TYPE_FROM_HANDLE( h ) )
      40                 :            :     {
      41                 :         12 :         storage.clear();
      42                 :         12 :         result    = thisMB->get_adjacencies( &h, 1, 0, false, storage );
      43                 :         12 :         vect_out  = &storage[0];
      44                 :         12 :         count_out = storage.size();
      45                 :            :     }
      46                 :            :     else
      47                 :            :     {
      48                 :     163475 :         result = thisMB->get_connectivity( h, vect_out, count_out, false, &storage );
      49                 :            :     }
      50                 :     163487 :     return result;
      51                 :            : }
      52                 :            : 
      53                 :        438 : AEntityFactory::AEntityFactory( Core* mdb )
      54                 :            : {
      55         [ -  + ]:        438 :     assert( NULL != mdb );
      56                 :        438 :     thisMB       = mdb;
      57                 :        438 :     mVertElemAdj = false;
      58                 :        438 : }
      59                 :            : 
      60                 :        435 : AEntityFactory::~AEntityFactory()
      61                 :            : {
      62                 :            :     // clean up all the adjacency information that was created
      63                 :            :     EntityType ent_type;
      64                 :            : 
      65                 :            :     // iterate through each element type
      66         [ +  + ]:       5655 :     for( ent_type = MBVERTEX; ent_type <= MBENTITYSET; ent_type++ )
      67                 :            :     {
      68                 :       5220 :         TypeSequenceManager::iterator i;
      69                 :       5220 :         TypeSequenceManager& seqman = thisMB->sequence_manager()->entity_map( ent_type );
      70         [ +  + ]:       7866 :         for( i = seqman.begin(); i != seqman.end(); ++i )
      71                 :            :         {
      72                 :       2646 :             std::vector< EntityHandle >** adj_list = ( *i )->data()->get_adjacency_data();
      73         [ +  + ]:       2646 :             if( !adj_list ) continue;
      74                 :        464 :             adj_list += ( *i )->start_handle() - ( *i )->data()->start_handle();
      75                 :            : 
      76         [ +  + ]:     392375 :             for( EntityID j = 0; j < ( *i )->size(); ++j )
      77                 :            :             {
      78         [ +  + ]:     391911 :                 delete adj_list[j];
      79                 :     391911 :                 adj_list[j] = 0;
      80                 :            :             }
      81                 :            :         }
      82                 :            :     }
      83                 :        435 : }
      84                 :            : 
      85                 :            : //! get the elements contained by source_entity, of
      86                 :            : //! type target_type, passing back in target_entities; if create_if_missing
      87                 :            : //! is true and no entity is found, one is created; if create_adjacency_option
      88                 :            : //! is >= 0, adjacencies from entities of that dimension to each target_entity
      89                 :            : //! are created (this function uses AEntityFactory::get_element for each element)
      90                 :          0 : ErrorCode AEntityFactory::get_elements( EntityHandle source_entity, const unsigned int target_dimension,
      91                 :            :                                         std::vector< EntityHandle >& target_entities, const bool create_if_missing,
      92                 :            :                                         const int create_adjacency_option )
      93                 :            : {
      94                 :            :     // check for trivial case first
      95                 :          0 :     const EntityType source_type    = TYPE_FROM_HANDLE( source_entity );
      96                 :          0 :     const unsigned source_dimension = CN::Dimension( source_type );
      97                 :            : 
      98 [ #  # ][ #  # ]:          0 :     if( source_type >= MBENTITYSET || target_dimension < 1 || target_dimension > 3 ) { return MB_TYPE_OUT_OF_RANGE; }
                 [ #  # ]
      99         [ #  # ]:          0 :     else if( source_dimension == target_dimension )
     100                 :            :     {
     101                 :          0 :         target_entities.push_back( source_entity );
     102                 :          0 :         return MB_SUCCESS;
     103                 :            :     }
     104                 :            : 
     105                 :            :     ErrorCode result;
     106         [ #  # ]:          0 :     if( mVertElemAdj == false )
     107                 :            :     {
     108                 :          0 :         result = create_vert_elem_adjacencies();
     109         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     110                 :            :     }
     111                 :            : 
     112         [ #  # ]:          0 :     if( source_dimension == 0 )
     113                 :            :     {
     114                 :            :         result = get_zero_to_n_elements( source_entity, target_dimension, target_entities, create_if_missing,
     115                 :          0 :                                          create_adjacency_option );
     116                 :            :     }
     117         [ #  # ]:          0 :     else if( source_dimension > target_dimension )
     118                 :            :     {
     119                 :            :         result = get_down_adjacency_elements( source_entity, target_dimension, target_entities, create_if_missing,
     120                 :          0 :                                               create_adjacency_option );
     121                 :            :     }
     122                 :            :     else  // if(source_dimension < target_dimension)
     123                 :            :     {
     124                 :            :         result = get_up_adjacency_elements( source_entity, target_dimension, target_entities, create_if_missing,
     125                 :          0 :                                             create_adjacency_option );
     126                 :            :     }
     127                 :            : 
     128                 :          0 :     return result;
     129                 :            : }
     130                 :            : 
     131                 :         22 : ErrorCode AEntityFactory::get_polyhedron_vertices( const EntityHandle source_entity,
     132                 :            :                                                    std::vector< EntityHandle >& target_entities )
     133                 :            : {
     134                 :            :     // get the connectivity array pointer
     135                 :         22 :     const EntityHandle* connect = NULL;
     136                 :         22 :     int num_connect             = 0;
     137         [ +  - ]:         22 :     ErrorCode result            = thisMB->get_connectivity( source_entity, connect, num_connect );
     138         [ -  + ]:         22 :     if( MB_SUCCESS != result ) return result;
     139                 :            : 
     140                 :            :     // now get the union of those polygons' vertices
     141         [ +  - ]:         22 :     result = thisMB->get_adjacencies( connect, num_connect, 0, false, target_entities, Interface::UNION );
     142                 :         22 :     return result;
     143                 :            : }
     144                 :            : 
     145                 :         35 : ErrorCode AEntityFactory::get_associated_meshsets( EntityHandle source_entity,
     146                 :            :                                                    std::vector< EntityHandle >& target_entities )
     147                 :            : {
     148                 :            : 
     149                 :            :     ErrorCode result;
     150                 :            : 
     151                 :            :     const EntityHandle* adj_vec;
     152                 :            :     int num_adj;
     153         [ +  - ]:         35 :     result = get_adjacencies( source_entity, adj_vec, num_adj );
     154 [ +  - ][ +  + ]:         35 :     if( result != MB_SUCCESS || adj_vec == NULL ) return result;
     155                 :            : 
     156                 :            :     // find the meshsets in this vector
     157                 :         31 :     DimensionPair dim_pair = CN::TypeDimensionMap[4];
     158                 :            :     int dum;
     159                 :            :     const EntityHandle* start_ent =
     160 [ +  - ][ +  - ]:         31 :         std::lower_bound( adj_vec, adj_vec + num_adj, CREATE_HANDLE( dim_pair.first, MB_START_ID, dum ) );
     161                 :            :     const EntityHandle* end_ent =
     162 [ +  - ][ +  - ]:         31 :         std::lower_bound( start_ent, adj_vec + num_adj, CREATE_HANDLE( dim_pair.second, MB_END_ID, dum ) );
     163                 :            : 
     164                 :            :     // copy the the meshsets
     165         [ +  - ]:         31 :     target_entities.insert( target_entities.end(), start_ent, end_ent );
     166                 :            : 
     167                 :         35 :     return result;
     168                 :            : }
     169                 :            : 
     170                 :            : //! get the element defined by the vertices in vertex_list, of the
     171                 :            : //! type target_type, passing back in target_entity; if create_if_missing
     172                 :            : //! is true and no entity is found, one is created; if create_adjacency_option
     173                 :            : //! is >= 0, adjacencies from entities of that dimension to target_entity
     174                 :            : //! are created (only create_adjacency_option=0 is supported right now,
     175                 :            : //! so that never creates other ancillary entities)
     176                 :     684211 : ErrorCode AEntityFactory::get_element( const EntityHandle* vertex_list, const int vertex_list_size,
     177                 :            :                                        const EntityType target_type, EntityHandle& target_entity,
     178                 :            :                                        const bool create_if_missing, const EntityHandle source_entity,
     179                 :            :                                        const int /*create_adjacency_option*/ )
     180                 :            : {
     181                 :            : 
     182                 :            :     // look over nodes to see if this entity already exists
     183                 :     684211 :     target_entity = 0;
     184                 :            :     ErrorCode result;
     185                 :            :     const EntityHandle *i_adj, *end_adj;
     186                 :            : 
     187                 :            :     // need vertex adjacencies, so create if necessary
     188 [ -  + ][ #  # ]:     684211 :     if( mVertElemAdj == false ) create_vert_elem_adjacencies();
     189                 :            : 
     190                 :            :     // get the adjacency list
     191                 :            :     const EntityHandle* adj_vec;
     192                 :            :     int num_adj;
     193         [ +  - ]:     684211 :     result = get_adjacencies( vertex_list[0], adj_vec, num_adj );
     194 [ +  - ][ -  + ]:     684211 :     if( result != MB_SUCCESS || adj_vec == NULL ) return result;
     195                 :            : 
     196                 :            :     // check to see if any of these are equivalent to the vertex list
     197                 :            :     int dum;
     198                 :            : 
     199                 :            :     // use a fixed-size array, for speed; there should never be more than 5 equivalent entities
     200                 :            :     EntityHandle temp_vec[15];
     201                 :     684211 :     int temp_vec_size = 0;
     202                 :            : 
     203 [ +  - ][ +  - ]:     684211 :     i_adj   = std::lower_bound( adj_vec, adj_vec + num_adj, CREATE_HANDLE( target_type, MB_START_ID, dum ) );
     204 [ +  - ][ +  - ]:     684211 :     end_adj = std::lower_bound( i_adj, adj_vec + num_adj, CREATE_HANDLE( target_type, MB_END_ID, dum ) );
     205         [ +  + ]:    3595652 :     for( ; i_adj != end_adj; ++i_adj )
     206                 :            :     {
     207 [ +  - ][ -  + ]:    2911441 :         if( TYPE_FROM_HANDLE( *i_adj ) != target_type ) continue;
     208                 :            : 
     209 [ +  - ][ +  + ]:    2911441 :         if( true == entities_equivalent( *i_adj, vertex_list, vertex_list_size, target_type ) )
     210                 :     315504 :         { temp_vec[temp_vec_size++] = *i_adj; }
     211                 :            :     }
     212                 :            : 
     213 [ +  + ][ +  + ]:     684211 :     if( temp_vec_size == 0 && !create_if_missing ) return result;
     214                 :            : 
     215                 :            :     // test for size against fixed-size array
     216         [ -  + ]:     408049 :     assert( temp_vec_size <= 15 );
     217                 :            : 
     218                 :            :     // test for empty first, 'cuz it's cheap
     219 [ +  + ][ +  - ]:     408049 :     if( temp_vec_size == 0 && true == create_if_missing )
     220                 :            :     {
     221                 :            : 
     222                 :            :         // Create the element with this handle (handle is a return type and should be the last
     223                 :            :         // parameter)
     224         [ +  - ]:      92630 :         result = thisMB->create_element( target_type, vertex_list, vertex_list_size, target_entity );
     225                 :            :     }
     226                 :            : 
     227                 :            :     // next most likely is one entity
     228         [ +  + ]:     315419 :     else if( temp_vec_size == 1 )
     229                 :     315364 :         target_entity = temp_vec[0];
     230                 :            : 
     231                 :            :     // least likely, most work - leave for last test
     232                 :            :     else
     233                 :            :     {
     234                 :            :         // multiple entities found - look for direct adjacencies
     235         [ +  + ]:         55 :         if( 0 != source_entity )
     236                 :            :         {
     237                 :            : 
     238                 :            :             int num_adjs;
     239         [ +  - ]:          3 :             for( dum = 0; dum < temp_vec_size; dum++ )
     240                 :            :             {
     241         [ +  - ]:          3 :                 result = get_adjacencies( temp_vec[dum], adj_vec, num_adjs );
     242 [ +  - ][ +  + ]:          3 :                 if( std::find( adj_vec, ( adj_vec + num_adjs ), source_entity ) != ( adj_vec + num_adjs ) )
     243                 :            :                 {
     244                 :            :                     // found it, return it
     245                 :          2 :                     target_entity = temp_vec[dum];
     246                 :          2 :                     break;
     247                 :            :                 }
     248                 :            :             }
     249                 :            : 
     250 [ -  + ][ #  # ]:          2 :             if( 0 == target_entity &&
                 [ -  + ]
     251 [ #  # ][ #  # ]:          0 :                 thisMB->dimension_from_handle( source_entity ) > CN::Dimension( target_type ) + 1 )
     252                 :            :             {
     253                 :            :                 // still have multiple entities, and source dimension is two greater than target,
     254                 :            :                 // so there may not be any explicit adjacencies between the two; look for common
     255                 :            :                 // entities of the intermediate dimension
     256         [ #  # ]:          0 :                 MeshTopoUtil mtu( thisMB );
     257         [ #  # ]:          0 :                 int intermed_dim = CN::Dimension( target_type ) + 1;
     258         [ #  # ]:          0 :                 for( dum = 0; dum < temp_vec_size; dum++ )
     259                 :            :                 {
     260 [ #  # ][ #  # ]:          0 :                     if( 0 != mtu.common_entity( temp_vec[dum], source_entity, intermed_dim ) )
     261                 :            :                     {
     262                 :          0 :                         target_entity = temp_vec[dum];
     263                 :          0 :                         break;
     264                 :            :                     }
     265                 :          2 :                 }
     266                 :            :             }
     267                 :            :         }
     268                 :            : 
     269         [ +  + ]:         55 :         if( target_entity == 0 )
     270                 :            :         {
     271                 :            :             // if we get here, we didn't find a matching adjacency; just take the first one, but
     272                 :            :             // return a non-success result
     273                 :         53 :             target_entity = temp_vec[0];
     274                 :         53 :             result        = MB_MULTIPLE_ENTITIES_FOUND;
     275                 :            :         }
     276                 :            :     }
     277                 :            : 
     278                 :     684211 :     return result;
     279                 :            : }
     280                 :            : 
     281                 :    2911441 : bool AEntityFactory::entities_equivalent( const EntityHandle this_entity, const EntityHandle* vertex_list,
     282                 :            :                                           const int vertex_list_size, const EntityType target_type )
     283                 :            : {
     284                 :            :     // compare vertices of this_entity with those in the list, returning true if they
     285                 :            :     // represent the same element
     286         [ +  - ]:    2911441 :     EntityType this_type = TYPE_FROM_HANDLE( this_entity );
     287                 :            : 
     288         [ -  + ]:    2911441 :     if( this_type != target_type )
     289                 :          0 :         return false;
     290                 :            : 
     291 [ -  + ][ #  # ]:    2911441 :     else if( this_type == MBVERTEX && ( vertex_list_size > 1 || vertex_list[0] != this_entity ) )
                 [ #  # ]
     292                 :          0 :         return false;
     293                 :            : 
     294                 :            :     // need to compare the actual vertices
     295                 :    2911441 :     const EntityHandle* this_vertices = NULL;
     296                 :    2911441 :     int num_this_vertices             = 0;
     297         [ +  - ]:    2911441 :     std::vector< EntityHandle > storage;
     298         [ +  - ]:    2911441 :     thisMB->get_connectivity( this_entity, this_vertices, num_this_vertices, false, &storage );
     299                 :            : 
     300                 :            :     // see if we can get one node id to match
     301         [ -  + ]:    2911441 :     assert( vertex_list_size > 0 );
     302                 :            :     int num_corner_verts =
     303         [ +  - ]:    2911416 :         ( ( this_type == MBPOLYGON || this_type == MBPOLYHEDRON ) ? num_this_vertices
     304 [ +  + ][ +  - ]:    5822857 :                                                                   : CN::VerticesPerEntity( target_type ) );
     305         [ +  - ]:    2911441 :     const EntityHandle* iter = std::find( this_vertices, ( this_vertices + num_corner_verts ), vertex_list[0] );
     306         [ -  + ]:    2911441 :     if( iter == ( this_vertices + num_corner_verts ) ) return false;
     307                 :            : 
     308                 :            :     // now lets do connectivity matching
     309                 :    2911441 :     bool they_match = true;
     310                 :            : 
     311                 :            :     // line up our vectors
     312                 :            :     int i;
     313                 :    2911441 :     int offset = iter - this_vertices;
     314                 :            : 
     315                 :            :     // first compare forward
     316         [ +  + ]:    3279724 :     for( i = 1; i < num_corner_verts; ++i )
     317                 :            :     {
     318         [ -  + ]:    2980786 :         if( i >= vertex_list_size )
     319                 :            :         {
     320                 :          0 :             they_match = false;
     321                 :          0 :             break;
     322                 :            :         }
     323                 :            : 
     324         [ +  + ]:    2980786 :         if( vertex_list[i] != this_vertices[( offset + i ) % num_corner_verts] )
     325                 :            :         {
     326                 :    2612503 :             they_match = false;
     327                 :    2612503 :             break;
     328                 :            :         }
     329                 :            :     }
     330                 :            : 
     331         [ +  + ]:    2911441 :     if( they_match == true ) return true;
     332                 :            : 
     333                 :    2612503 :     they_match = true;
     334                 :            : 
     335                 :            :     // then compare reverse
     336                 :            :     // offset iter to avoid addition inside loop; this just makes sure we don't
     337                 :            :     // go off beginning of this_vertices with an index < 0
     338                 :    2612503 :     offset += num_corner_verts;
     339         [ +  + ]:    2700035 :     for( i = 1; i < num_corner_verts; i++ )
     340                 :            :     {
     341         [ +  + ]:    2683469 :         if( vertex_list[i] != this_vertices[( offset - i ) % num_corner_verts] )
     342                 :            :         {
     343                 :    2595937 :             they_match = false;
     344                 :    2595937 :             break;
     345                 :            :         }
     346                 :            :     }
     347                 :    2911441 :     return they_match;
     348                 :            : }
     349                 :            : 
     350                 :            : //! add an adjacency from from_ent to to_ent; if both_ways is true, add one
     351                 :            : //! in reverse too
     352                 :            : //! NOTE: this function is defined even though we may only be implementing
     353                 :            : //! vertex-based up-adjacencies
     354                 :    1410354 : ErrorCode AEntityFactory::add_adjacency( EntityHandle from_ent, EntityHandle to_ent, const bool both_ways )
     355                 :            : {
     356         [ +  - ]:    1410354 :     EntityType to_type = TYPE_FROM_HANDLE( to_ent );
     357                 :            : 
     358         [ -  + ]:    1410354 :     if( to_type == MBVERTEX ) return MB_ALREADY_ALLOCATED;
     359                 :            : 
     360                 :    1410354 :     AdjacencyVector* adj_list_ptr = NULL;
     361         [ +  - ]:    1410354 :     ErrorCode result              = get_adjacencies( from_ent, adj_list_ptr, true );
     362         [ +  + ]:    1410354 :     if( MB_SUCCESS != result ) return result;
     363                 :            : 
     364                 :            :     // get an iterator to the right spot in this sorted vector
     365                 :    1410310 :     AdjacencyVector::iterator adj_iter;
     366         [ +  + ]:    1410310 :     if( !adj_list_ptr->empty() )
     367                 :            :     {
     368         [ +  - ]:    1053722 :         adj_iter = std::lower_bound( adj_list_ptr->begin(), adj_list_ptr->end(), to_ent );
     369                 :            : 
     370 [ +  - ][ +  + ]:    1053722 :         if( adj_iter == adj_list_ptr->end() || to_ent != *adj_iter ) { adj_list_ptr->insert( adj_iter, to_ent ); }
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
         [ +  - ][ #  # ]
     371                 :            :     }
     372                 :            :     else
     373         [ +  - ]:     356588 :         adj_list_ptr->push_back( to_ent );
     374                 :            : 
     375                 :            :     // if both_ways is true, recursively call this function
     376 [ +  + ][ +  - ]:    1410310 :     if( true == both_ways && to_type != MBVERTEX ) result = add_adjacency( to_ent, from_ent, false );
                 [ +  - ]
     377                 :            : 
     378                 :    1410354 :     return result;
     379                 :            : }
     380                 :            : 
     381                 :            : //! remove an adjacency from from the base_entity.
     382                 :      71920 : ErrorCode AEntityFactory::remove_adjacency( EntityHandle base_entity, EntityHandle adj_to_remove )
     383                 :            : {
     384                 :            :     ErrorCode result;
     385                 :            : 
     386 [ +  - ][ +  + ]:      71920 :     if( TYPE_FROM_HANDLE( base_entity ) == MBENTITYSET )
     387         [ +  - ]:        100 :         return thisMB->remove_entities( base_entity, &adj_to_remove, 1 );
     388                 :            : 
     389                 :            :     // get the adjacency tag
     390                 :      71820 :     AdjacencyVector* adj_list = NULL;
     391         [ +  - ]:      71820 :     result                    = get_adjacencies( base_entity, adj_list );
     392 [ +  + ][ -  + ]:      71820 :     if( adj_list == NULL || MB_SUCCESS != result ) return result;
     393                 :            : 
     394                 :            :     // remove the specified entity from the adjacency list and truncate
     395                 :            :     // the list to the new length
     396 [ +  - ][ +  - ]:      71811 :     adj_list->erase( std::remove( adj_list->begin(), adj_list->end(), adj_to_remove ), adj_list->end() );
     397                 :            : 
     398                 :      71920 :     return result;
     399                 :            : }
     400                 :            : 
     401                 :            : //! remove all adjacencies from from the base_entity.
     402                 :      53857 : ErrorCode AEntityFactory::remove_all_adjacencies( EntityHandle base_entity, const bool delete_adj_list )
     403                 :            : {
     404                 :            :     ErrorCode result;
     405         [ +  - ]:      53857 :     EntityType base_type = TYPE_FROM_HANDLE( base_entity );
     406                 :            : 
     407 [ +  + ][ +  - ]:      53857 :     if( base_type == MBENTITYSET ) return thisMB->clear_meshset( &base_entity, 1 );
     408         [ +  - ]:      24285 :     const int base_ent_dim = CN::Dimension( base_type );
     409                 :            : 
     410                 :            :     // Remove adjacencies from element vertices back to
     411                 :            :     // this element.  Also check any elements adjacent
     412                 :            :     // to the vertex and of higher dimension than this
     413                 :            :     // element for downward adjacencies to this element.
     414 [ +  - ][ +  + ]:      24285 :     if( vert_elem_adjacencies() && base_type != MBVERTEX )
         [ +  + ][ +  + ]
     415                 :            :     {
     416                 :      23390 :         EntityHandle const *connvect = 0, *adjvect = 0;
     417                 :      23390 :         int numconn = 0, numadj = 0;
     418         [ +  - ]:      23390 :         std::vector< EntityHandle > connstorage;
     419         [ +  - ]:      23390 :         result = get_vertices( base_entity, connvect, numconn, connstorage );
     420         [ -  + ]:      23390 :         if( MB_SUCCESS != result ) return result;
     421                 :            : 
     422 [ +  + ][ +  - ]:      90143 :         for( int i = 0; i < numconn; ++i )
     423                 :            :         {
     424         [ +  - ]:      66753 :             result = get_adjacencies( connvect[i], adjvect, numadj );
     425         [ -  + ]:      66753 :             if( MB_SUCCESS != result ) return result;
     426                 :            : 
     427                 :      66753 :             bool remove_this = false;
     428         [ +  + ]:    2544130 :             for( int j = 0; j < numadj; ++j )
     429                 :            :             {
     430         [ +  + ]:    2477377 :                 if( adjvect[j] == base_entity ) remove_this = true;
     431                 :            : 
     432 [ +  - ][ +  - ]:    3987750 :                 if( CN::Dimension( TYPE_FROM_HANDLE( adjvect[j] ) ) != base_ent_dim &&
         [ +  + ][ -  + ]
                 [ -  + ]
     433         [ +  - ]:    1510373 :                     explicitly_adjacent( adjvect[j], base_entity ) )
     434         [ #  # ]:          0 :                     remove_adjacency( adjvect[j], base_entity );
     435                 :            :             }
     436                 :            : 
     437 [ +  - ][ +  - ]:      66753 :             if( remove_this ) remove_adjacency( connvect[i], base_entity );
     438                 :      23390 :         }
     439                 :            :     }
     440                 :            : 
     441                 :            :     // get the adjacency tag
     442                 :      24285 :     AdjacencyVector* adj_list = 0;
     443         [ +  - ]:      24285 :     result                    = get_adjacencies( base_entity, adj_list );
     444 [ +  - ][ +  + ]:      24285 :     if( MB_SUCCESS != result || !adj_list ) return result;
     445                 :            : 
     446                 :            :     // check adjacent entities for references back to this entity
     447 [ +  - ][ +  - ]:        621 :     for( AdjacencyVector::reverse_iterator it = adj_list->rbegin(); it != adj_list->rend(); ++it )
                 [ +  + ]
     448 [ +  - ][ +  - ]:        101 :         remove_adjacency( *it, base_entity );
     449                 :            : 
     450         [ +  - ]:        520 :     if( delete_adj_list )
     451         [ +  - ]:        520 :         result = set_adjacency_ptr( base_entity, NULL );
     452                 :            :     else
     453                 :          0 :         adj_list->clear();
     454                 :            : 
     455                 :      53857 :     return MB_SUCCESS;
     456                 :            : }
     457                 :            : 
     458                 :        185 : ErrorCode AEntityFactory::create_vert_elem_adjacencies()
     459                 :            : {
     460                 :            : 
     461                 :        185 :     mVertElemAdj = true;
     462                 :            : 
     463                 :            :     EntityType ent_type;
     464         [ +  - ]:        185 :     Range::iterator i_range;
     465                 :            :     const EntityHandle* connectivity;
     466         [ +  - ]:        185 :     std::vector< EntityHandle > aux_connect;
     467                 :            :     int number_nodes;
     468                 :            :     ErrorCode result;
     469         [ +  - ]:        370 :     Range handle_range;
     470                 :            : 
     471                 :            :     // 1. over all element types, for each element, create vertex-element adjacencies
     472 [ +  - ][ +  + ]:       1947 :     for( ent_type = MBEDGE; ent_type != MBENTITYSET; ent_type++ )
     473                 :            :     {
     474         [ +  - ]:       1806 :         handle_range.clear();
     475                 :            : 
     476                 :            :         // get this type of entity
     477         [ +  - ]:       1806 :         result = thisMB->get_entities_by_type( 0, ent_type, handle_range );
     478         [ -  + ]:       1806 :         if( result != MB_SUCCESS ) return result;
     479                 :            : 
     480 [ +  - ][ +  - ]:     141859 :         for( i_range = handle_range.begin(); i_range != handle_range.end(); ++i_range )
         [ +  - ][ +  - ]
                 [ +  + ]
     481                 :            :         {
     482 [ +  - ][ +  - ]:     140097 :             result = get_vertices( *i_range, connectivity, number_nodes, aux_connect );
     483         [ -  + ]:     140097 :             if( MB_SUCCESS != result ) return result;
     484                 :            : 
     485                 :            :             // add the adjacency
     486         [ +  + ]:     700307 :             for( int k = 0; k < number_nodes; k++ )
     487 [ +  - ][ +  - ]:     560254 :                 if( ( result = add_adjacency( connectivity[k], *i_range ) ) != MB_SUCCESS ) return result;
                 [ +  + ]
     488                 :            :         }
     489                 :            :     }
     490                 :            : 
     491                 :        326 :     return MB_SUCCESS;
     492                 :            : }
     493                 :            : 
     494                 :    2298523 : ErrorCode AEntityFactory::get_adjacencies( EntityHandle entity, const EntityHandle*& adjacent_entities,
     495                 :            :                                            int& num_entities ) const
     496                 :            : {
     497                 :    2298523 :     AdjacencyVector const* vec_ptr = 0;
     498         [ +  - ]:    2298523 :     ErrorCode result               = get_adjacency_ptr( entity, vec_ptr );
     499 [ +  - ][ +  + ]:    2298523 :     if( MB_SUCCESS != result || !vec_ptr )
     500                 :            :     {
     501                 :    1545645 :         adjacent_entities = 0;
     502                 :    1545645 :         num_entities      = 0;
     503                 :    1545645 :         return result;
     504                 :            :     }
     505                 :            : 
     506                 :     752878 :     num_entities      = vec_ptr->size();
     507 [ +  + ][ +  - ]:     752878 :     adjacent_entities = ( vec_ptr->empty() ) ? NULL : &( ( *vec_ptr )[0] );
     508                 :    2298523 :     return MB_SUCCESS;
     509                 :            : }
     510                 :            : 
     511                 :     343602 : ErrorCode AEntityFactory::get_adjacencies( EntityHandle entity, std::vector< EntityHandle >& adjacent_entities ) const
     512                 :            : {
     513                 :     343602 :     AdjacencyVector const* vec_ptr = 0;
     514         [ +  - ]:     343602 :     ErrorCode result               = get_adjacency_ptr( entity, vec_ptr );
     515 [ +  - ][ +  + ]:     343602 :     if( MB_SUCCESS != result || !vec_ptr )
     516                 :            :     {
     517                 :     275439 :         adjacent_entities.clear();
     518                 :     275439 :         return result;
     519                 :            :     }
     520                 :            : 
     521         [ +  - ]:      68163 :     adjacent_entities = *vec_ptr;
     522                 :     343602 :     return MB_SUCCESS;
     523                 :            : }
     524                 :            : 
     525                 :    2924342 : ErrorCode AEntityFactory::get_adjacencies( EntityHandle entity, std::vector< EntityHandle >*& adj_vec, bool create )
     526                 :            : {
     527                 :    2924342 :     adj_vec          = 0;
     528                 :    2924342 :     ErrorCode result = get_adjacency_ptr( entity, adj_vec );
     529 [ +  + ][ +  + ]:    2924342 :     if( MB_SUCCESS == result && !adj_vec && create )
                 [ +  + ]
     530                 :            :     {
     531         [ +  - ]:     356333 :         adj_vec = new AdjacencyVector;
     532                 :     356333 :         result  = set_adjacency_ptr( entity, adj_vec );
     533         [ -  + ]:     356333 :         if( MB_SUCCESS != result )
     534                 :            :         {
     535         [ #  # ]:          0 :             delete adj_vec;
     536                 :          0 :             adj_vec = 0;
     537                 :            :         }
     538                 :            :     }
     539                 :    2924342 :     return result;
     540                 :            : }
     541                 :            : 
     542                 :    1502958 : ErrorCode AEntityFactory::get_adjacencies( const EntityHandle source_entity, const unsigned int target_dimension,
     543                 :            :                                            bool create_if_missing, std::vector< EntityHandle >& target_entities )
     544                 :            : {
     545                 :    1502958 :     const EntityType source_type    = TYPE_FROM_HANDLE( source_entity );
     546                 :    1502958 :     const unsigned source_dimension = CN::Dimension( source_type );
     547                 :            : 
     548                 :            :     ErrorCode result;
     549         [ +  + ]:    1502958 :     if( target_dimension == 4 )
     550                 :            :     {  // get meshsets 'source' is in
     551                 :         35 :         result = get_associated_meshsets( source_entity, target_entities );
     552                 :            :     }
     553 [ +  + ][ +  + ]:    1502923 :     else if( target_dimension == ( source_type != MBPOLYHEDRON ? 0 : 2 ) )
     554                 :            :     {
     555         [ +  - ]:        260 :         std::vector< EntityHandle > tmp_storage;
     556                 :        260 :         const EntityHandle* conn = NULL;
     557                 :        260 :         int len                  = 0;
     558         [ +  - ]:        260 :         result                   = thisMB->get_connectivity( source_entity, conn, len, false, &tmp_storage );
     559         [ +  - ]:        260 :         target_entities.insert( target_entities.end(), conn, conn + len );
     560                 :            :     }
     561 [ +  + ][ +  - ]:    1502663 :     else if( target_dimension == 0 && source_type == MBPOLYHEDRON )
     562                 :            :     {
     563                 :         22 :         result = get_polyhedron_vertices( source_entity, target_entities );
     564                 :            :     }
     565         [ -  + ]:    1502641 :     else if( source_dimension == target_dimension )
     566                 :            :     {
     567                 :          0 :         target_entities.push_back( source_entity );
     568                 :          0 :         result = MB_SUCCESS;
     569                 :            :     }
     570                 :            :     else
     571                 :            :     {
     572         [ +  + ]:    1502641 :         if( mVertElemAdj == false )
     573                 :            :         {
     574                 :        172 :             result = create_vert_elem_adjacencies();
     575         [ +  + ]:        172 :             if( MB_SUCCESS != result ) return result;
     576                 :            :         }
     577                 :            : 
     578         [ +  + ]:    1502599 :         if( source_dimension == 0 )
     579                 :    1305114 :         { result = get_zero_to_n_elements( source_entity, target_dimension, target_entities, create_if_missing ); }
     580         [ +  + ]:     197485 :         else if( source_dimension > target_dimension )
     581                 :            :         {
     582                 :     142352 :             result = get_down_adjacency_elements( source_entity, target_dimension, target_entities, create_if_missing );
     583                 :            :         }
     584                 :            :         else  // if(source_dimension < target_dimension)
     585                 :            :         {
     586                 :      55133 :             result = get_up_adjacency_elements( source_entity, target_dimension, target_entities, create_if_missing );
     587                 :            :         }
     588                 :            :     }
     589                 :            : 
     590                 :    1502958 :     return result;
     591                 :            : }
     592                 :            : 
     593                 :     476084 : ErrorCode AEntityFactory::notify_create_entity( const EntityHandle entity, const EntityHandle* node_array,
     594                 :            :                                                 const int number_nodes )
     595                 :            : {
     596                 :     476084 :     ErrorCode result = MB_SUCCESS, tmp_result;
     597         [ +  + ]:     476084 :     if( vert_elem_adjacencies() )
     598                 :            :     {
     599                 :            :         // iterate through nodes and add adjacency information
     600         [ +  + ]:     172298 :         if( TYPE_FROM_HANDLE( entity ) == MBPOLYHEDRON )
     601                 :            :         {
     602                 :            :             // polyhedron - get real vertex connectivity
     603         [ +  - ]:          4 :             std::vector< EntityHandle > verts;
     604         [ +  - ]:          4 :             tmp_result = get_adjacencies( entity, 0, false, verts );
     605         [ -  + ]:          4 :             if( MB_SUCCESS != tmp_result ) return tmp_result;
     606 [ +  - ][ +  - ]:         20 :             for( std::vector< EntityHandle >::iterator vit = verts.begin(); vit != verts.end(); ++vit )
         [ +  + ][ +  - ]
     607                 :            :             {
     608 [ +  - ][ +  - ]:         16 :                 tmp_result = add_adjacency( *vit, entity );
     609         [ -  + ]:         16 :                 if( MB_SUCCESS != tmp_result ) result = tmp_result;
     610                 :          4 :             }
     611                 :            :         }
     612                 :            :         else
     613                 :            :         {
     614         [ +  + ]:     742834 :             for( unsigned int i = number_nodes; i--; )
     615                 :            :             {
     616                 :     570536 :                 tmp_result = add_adjacency( node_array[i], entity );
     617         [ -  + ]:     570536 :                 if( MB_SUCCESS != tmp_result ) result = tmp_result;
     618                 :            :             }
     619                 :            :         }
     620                 :            :     }
     621                 :            : 
     622                 :     476084 :     return result;
     623                 :            : }
     624                 :            : 
     625                 :    1417832 : ErrorCode AEntityFactory::get_zero_to_n_elements( EntityHandle source_entity, const unsigned int target_dimension,
     626                 :            :                                                   std::vector< EntityHandle >& target_entities,
     627                 :            :                                                   const bool create_if_missing,
     628                 :            :                                                   const int /*create_adjacency_option = -1*/ )
     629                 :            : {
     630                 :    1417832 :     AdjacencyVector::iterator start_ent, end_ent;
     631                 :            : 
     632                 :            :     // get the adjacency vector
     633                 :    1417832 :     AdjacencyVector* adj_vec = NULL;
     634         [ +  - ]:    1417832 :     ErrorCode result         = get_adjacencies( source_entity, adj_vec );
     635 [ +  - ][ +  + ]:    1417832 :     if( result != MB_SUCCESS || adj_vec == NULL ) return result;
     636                 :            : 
     637 [ +  + ][ +  + ]:    1416542 :     if( target_dimension < 3 && create_if_missing )
     638                 :            :     {
     639         [ +  - ]:       3621 :         std::vector< EntityHandle > tmp_ents;
     640                 :            : 
     641                 :            :         start_ent = std::lower_bound( adj_vec->begin(), adj_vec->end(),
     642 [ +  - ][ +  - ]:       3621 :                                       FIRST_HANDLE( CN::TypeDimensionMap[target_dimension + 1].first ) );
     643                 :            : 
     644 [ +  - ][ +  - ]:       3621 :         end_ent = std::lower_bound( start_ent, adj_vec->end(), LAST_HANDLE( CN::TypeDimensionMap[3].second ) );
     645                 :            : 
     646         [ +  - ]:       7242 :         std::vector< EntityHandle > elems( start_ent, end_ent );
     647                 :            : 
     648                 :            :         // make target_dimension elements from all adjacient higher-dimension elements
     649 [ +  - ][ +  - ]:      26136 :         for( start_ent = elems.begin(); start_ent != elems.end(); ++start_ent )
                 [ +  + ]
     650                 :            :         {
     651                 :      22515 :             tmp_ents.clear();
     652 [ +  - ][ +  - ]:      22515 :             get_down_adjacency_elements( *start_ent, target_dimension, tmp_ents, create_if_missing, 0 );
     653                 :       3621 :         }
     654                 :            :     }
     655                 :            : 
     656                 :    1416542 :     DimensionPair dim_pair = CN::TypeDimensionMap[target_dimension];
     657 [ +  - ][ +  - ]:    1416542 :     start_ent              = std::lower_bound( adj_vec->begin(), adj_vec->end(), FIRST_HANDLE( dim_pair.first ) );
     658 [ +  - ][ +  - ]:    1416542 :     end_ent                = std::lower_bound( start_ent, adj_vec->end(), LAST_HANDLE( dim_pair.second ) );
     659         [ +  - ]:    1416542 :     target_entities.insert( target_entities.end(), start_ent, end_ent );
     660                 :    1417832 :     return MB_SUCCESS;
     661                 :            : }
     662                 :            : 
     663                 :     164867 : ErrorCode AEntityFactory::get_down_adjacency_elements( EntityHandle source_entity, const unsigned int target_dimension,
     664                 :            :                                                        std::vector< EntityHandle >& target_entities,
     665                 :            :                                                        const bool create_if_missing, const int create_adjacency_option )
     666                 :            : {
     667                 :            : 
     668         [ +  - ]:     164867 :     EntityType source_type = TYPE_FROM_HANDLE( source_entity );
     669                 :            : 
     670 [ +  + ][ +  + ]:     164867 :     if( source_type == MBPOLYHEDRON || source_type == MBPOLYGON )
     671                 :            :         return get_down_adjacency_elements_poly( source_entity, target_dimension, target_entities, create_if_missing,
     672         [ +  - ]:        260 :                                                  create_adjacency_option );
     673                 :            : 
     674                 :            :     // make this a fixed size to avoid cost of working with STL vectors
     675                 :     164607 :     EntityHandle vertex_array[27] = {};
     676                 :            :     ErrorCode temp_result;
     677                 :            : 
     678                 :     164607 :     const EntityHandle* vertices = NULL;
     679                 :     164607 :     int num_verts                = 0;
     680                 :            : 
     681                 :            :     // I know there are already vertex adjacencies for this - call
     682                 :            :     // another function to get them
     683         [ +  - ]:     164607 :     std::vector< EntityHandle > storage;
     684         [ +  - ]:     164607 :     ErrorCode result = thisMB->get_connectivity( source_entity, vertices, num_verts, false, &storage );
     685         [ -  + ]:     164607 :     if( MB_SUCCESS != result ) return result;
     686                 :            : 
     687                 :            :     int has_mid_nodes[4];
     688         [ +  - ]:     164607 :     CN::HasMidNodes( source_type, num_verts, has_mid_nodes );
     689                 :            : 
     690         [ +  - ]:     329214 :     std::vector< int > index_list;
     691         [ +  - ]:     164607 :     int num_sub_ents = CN::NumSubEntities( source_type, target_dimension );
     692                 :            : 
     693         [ +  + ]:     793685 :     for( int j = 0; j < num_sub_ents; j++ )
     694                 :            :     {
     695                 :     629078 :         const CN::ConnMap& cmap = CN::mConnectivityMap[source_type][target_dimension - 1];
     696                 :            : 
     697                 :     629078 :         int verts_per_sub = cmap.num_corners_per_sub_element[j];
     698                 :            : 
     699                 :            :         // get the corner vertices
     700         [ +  + ]:    2279334 :         for( int i = 0; i < verts_per_sub; i++ )
     701                 :    1650256 :             vertex_array[i] = vertices[cmap.conn[j][i]];
     702                 :            : 
     703                 :            :         // get the ho nodes for sub-subfacets
     704 [ -  + ][ #  # ]:     629078 :         if( has_mid_nodes[1] && target_dimension > 1 )
     705                 :            :         {
     706                 :            :             // has edge mid-nodes; for each edge, get the right mid-node and put in vertices
     707                 :            :             // first get the edge indices
     708                 :          0 :             index_list.clear();
     709         [ #  # ]:          0 :             int int_result = CN::AdjacentSubEntities( source_type, &j, 1, target_dimension, 1, index_list );
     710         [ #  # ]:          0 :             if( 0 != int_result ) return MB_FAILURE;
     711         [ #  # ]:          0 :             for( unsigned int k = 0; k < index_list.size(); k++ )
     712                 :            :             {
     713 [ #  # ][ #  # ]:          0 :                 int tmp_index = CN::HONodeIndex( source_type, num_verts, 1, index_list[k] );
     714         [ #  # ]:          0 :                 if( tmp_index >= (int)num_verts ) return MB_INDEX_OUT_OF_RANGE;
     715                 :            : 
     716                 :            :                 // put this vertex on the end; reuse verts_per_sub as an index
     717                 :          0 :                 vertex_array[verts_per_sub++] = vertices[tmp_index];
     718                 :            :             }
     719                 :            :         }
     720                 :            :         // get the ho nodes for the target dimension
     721         [ -  + ]:     629078 :         if( has_mid_nodes[target_dimension] )
     722                 :            :         {
     723                 :            :             // get the ho node index for this subfacet
     724         [ #  # ]:          0 :             int tmp_index = CN::HONodeIndex( source_type, num_verts, target_dimension, j );
     725         [ #  # ]:          0 :             if( tmp_index >= num_verts ) return MB_INDEX_OUT_OF_RANGE;
     726                 :          0 :             vertex_array[verts_per_sub++] = vertices[tmp_index];
     727                 :            :         }
     728                 :            : 
     729                 :     629078 :         EntityHandle tmp_target = 0;
     730                 :     629078 :         temp_result = get_element( vertex_array, verts_per_sub, cmap.target_type[j], tmp_target, create_if_missing,
     731         [ +  - ]:     629078 :                                    source_entity, create_adjacency_option );
     732                 :            : 
     733         [ -  + ]:     629078 :         if( temp_result != MB_SUCCESS )
     734                 :          0 :             result = temp_result;
     735         [ +  + ]:     629078 :         else if( 0 != tmp_target )
     736         [ +  - ]:     352916 :             target_entities.push_back( tmp_target );
     737                 :            : 
     738                 :            :         // make sure we're not writing past the end of our fixed-size array
     739         [ -  + ]:     629078 :         if( verts_per_sub > 27 ) return MB_INDEX_OUT_OF_RANGE;
     740                 :            :     }
     741                 :            : 
     742                 :     329474 :     return result;
     743                 :            : }
     744                 :            : 
     745                 :        260 : ErrorCode AEntityFactory::get_down_adjacency_elements_poly( EntityHandle source_entity,
     746                 :            :                                                             const unsigned int target_dimension,
     747                 :            :                                                             std::vector< EntityHandle >& target_entities,
     748                 :            :                                                             const bool create_if_missing,
     749                 :            :                                                             const int /*create_adjacency_option*/ )
     750                 :            : {
     751                 :            : 
     752         [ +  - ]:        260 :     EntityType source_type = TYPE_FROM_HANDLE( source_entity );
     753                 :            : 
     754 [ +  + ][ +  - ]:        260 :     if( !( source_type == MBPOLYHEDRON && target_dimension > 0 && target_dimension < 3 ) &&
         [ -  + ][ +  - ]
     755         [ -  + ]:        258 :         !( source_type == MBPOLYGON && target_dimension == 1 ) )
     756                 :          0 :         return MB_TYPE_OUT_OF_RANGE;
     757                 :            : 
     758                 :            :     // make this a fixed size to avoid cost of working with STL vectors
     759         [ +  - ]:        260 :     std::vector< EntityHandle > vertex_array;
     760                 :            : 
     761                 :            :     // I know there are already vertex adjacencies for this - call
     762                 :            :     // another function to get them
     763         [ +  - ]:        260 :     ErrorCode result = get_adjacencies( source_entity, 0, false, vertex_array );
     764         [ -  + ]:        260 :     if( MB_SUCCESS != result ) return result;
     765                 :            : 
     766                 :            :     ErrorCode tmp_result;
     767         [ +  + ]:        260 :     if( source_type == MBPOLYGON )
     768                 :            :     {
     769                 :        258 :         result = MB_SUCCESS;
     770                 :            :         // put the first vertex on the end so we have a ring
     771 [ +  - ][ +  - ]:        258 :         vertex_array.push_back( *vertex_array.begin() );
     772         [ +  + ]:       1260 :         for( unsigned int i = 0; i < vertex_array.size() - 1; i++ )
     773                 :            :         {
     774 [ +  - ][ +  - ]:       2004 :             Range vrange, adj_edges;
              [ +  -  - ]
     775 [ +  - ][ +  - ]:       1002 :             vrange.insert( vertex_array[i] );
     776 [ +  - ][ +  - ]:       1002 :             vrange.insert( vertex_array[i + 1] );
     777                 :            :             // account for padded polygons; if the vertices are the same, skip
     778 [ +  - ][ -  + ]:       1002 :             if( vrange.size() == 1 ) continue;
     779         [ +  - ]:       1002 :             tmp_result = thisMB->get_adjacencies( vrange, 1, false, adj_edges );
     780         [ -  + ]:       1002 :             if( MB_SUCCESS != tmp_result ) result = tmp_result;
     781 [ +  - ][ +  + ]:       1002 :             if( adj_edges.size() == 1 )
     782                 :            :             {
     783                 :            :                 // single edge - don't check adjacencies
     784 [ +  - ][ +  - ]:        597 :                 target_entities.push_back( *adj_edges.begin() );
                 [ +  - ]
     785                 :            :             }
     786 [ +  - ][ -  + ]:        405 :             else if( adj_edges.size() != 0 )
     787                 :            :             {
     788                 :            :                 // multiple ones - need to check for explicit adjacencies
     789                 :          0 :                 unsigned int start_sz = target_entities.size();
     790                 :            :                 const EntityHandle* explicit_adjs;
     791                 :            :                 int num_exp;
     792 [ #  # ][ #  # ]:          0 :                 for( Range::iterator rit = adj_edges.begin(); rit != adj_edges.end(); ++rit )
         [ #  # ][ #  # ]
                 [ #  # ]
     793                 :            :                 {
     794                 :            :                     // TODO check return value
     795 [ #  # ][ #  # ]:          0 :                     this->get_adjacencies( *rit, explicit_adjs, num_exp );
     796 [ #  # ][ #  # ]:          0 :                     if( NULL != explicit_adjs &&
                 [ #  # ]
     797         [ #  # ]:          0 :                         std::find( explicit_adjs, explicit_adjs + num_exp, source_entity ) != explicit_adjs + num_exp )
     798 [ #  # ][ #  # ]:          0 :                         target_entities.push_back( *rit );
     799                 :            :                 }
     800         [ #  # ]:          0 :                 if( target_entities.size() == start_sz )
     801                 :            :                 {
     802                 :          0 :                     result = MB_MULTIPLE_ENTITIES_FOUND;
     803 [ #  # ][ #  # ]:          0 :                     target_entities.push_back( *adj_edges.begin() );
                 [ #  # ]
     804                 :            :                 }
     805                 :            :             }
     806                 :            :             else
     807                 :            :             {
     808                 :            :                 // we have no adjacent edge yet; we need to create one and also add
     809                 :            :                 // them to the adjacency of the vertices
     810         [ +  + ]:        405 :                 if( create_if_missing )
     811                 :            :                 {
     812                 :            :                     EntityHandle newEdge;
     813 [ +  - ][ +  - ]:        401 :                     EntityHandle v[2] = { vertex_array[i], vertex_array[i + 1] };
     814         [ +  - ]:        401 :                     result            = thisMB->create_element( MBEDGE, v, 2, newEdge );
     815         [ -  + ]:       1403 :                     if( MB_SUCCESS != result ) return result;
              [ +  -  - ]
     816                 :            :                     // we also need to add explicit adjacency, so next time we do not
     817                 :            :                     // create again (because we do not find the edge if it is not adjacent to the
     818                 :            :                     // vertices
     819                 :            :                     // if (create_adjacency_option >= 0)
     820                 :            :                     //{
     821         [ +  - ]:        401 :                     result = add_adjacency( v[0], newEdge );
     822         [ -  + ]:        401 :                     if( MB_SUCCESS != result ) return result;
     823         [ +  - ]:        401 :                     result = add_adjacency( v[1], newEdge );
     824         [ -  + ]:        401 :                     if( MB_SUCCESS != result ) return result;
     825         [ +  - ]:        401 :                     target_entities.push_back( newEdge );
     826                 :            :                     //}
     827                 :            :                 }
     828                 :            :             }
     829                 :       1002 :         }
     830                 :        258 :         return result;
     831                 :            :     }
     832                 :            : 
     833                 :            :     else
     834                 :            :     {
     835 [ -  + ][ #  # ]:          2 :         if( target_dimension == 2 ) { result = thisMB->get_connectivity( &source_entity, 1, target_entities ); }
     836                 :            :         else
     837                 :            :         {
     838         [ +  - ]:          2 :             std::vector< EntityHandle > dum_vec;
     839         [ +  - ]:          2 :             result = thisMB->get_connectivity( &source_entity, 1, dum_vec );
     840         [ -  + ]:          2 :             if( MB_SUCCESS != result ) return result;
     841         [ +  - ]:          2 :             result = thisMB->get_adjacencies( &dum_vec[0], dum_vec.size(), 1, create_if_missing, target_entities,
     842         [ +  - ]:          2 :                                               Interface::UNION );
     843                 :          2 :             return result;
     844                 :            :         }
     845                 :            :     }
     846                 :            : 
     847                 :        260 :     return MB_SUCCESS;
     848                 :            : }
     849                 :            : 
     850                 :            : #if 0
     851                 :            : // Do in-place set intersect of two *sorted* containers.
     852                 :            : // First container is modifed.  Second is not.
     853                 :            : // First container must allow assignment through iterators (in practice,
     854                 :            : // must be a container that does not enforce ordering, such
     855                 :            : // as std::vector, std::list, or a c-style array)
     856                 :            : template <typename T1, typename T2>
     857                 :            : static inline T1 intersect( T1 set1_begin, T1 set1_end,
     858                 :            :                             T2 set2_begin, T2 set2_end )
     859                 :            : {
     860                 :            :   T1 set1_write = set1_begin;
     861                 :            :   while (set1_begin != set1_end) {
     862                 :            :     if (set2_begin == set2_end)
     863                 :            :       return set1_write;
     864                 :            :     while (*set2_begin < *set1_begin)
     865                 :            :       if (++set2_begin == set2_end)
     866                 :            :         return set1_write;
     867                 :            :     if (!(*set1_begin < *set2_begin)) {
     868                 :            :       *set1_write = *set1_begin;
     869                 :            :       ++set1_write;
     870                 :            :       ++set2_begin;
     871                 :            :     }
     872                 :            :     ++set1_begin;
     873                 :            :   }
     874                 :            :   return set1_write;
     875                 :            : }
     876                 :            : 
     877                 :            : 
     878                 :            : ErrorCode AEntityFactory::get_up_adjacency_elements(
     879                 :            :                                    EntityHandle source_entity,
     880                 :            :                                    const unsigned int target_dimension,
     881                 :            :                                    std::vector<EntityHandle>& target_entities,
     882                 :            :                                    const bool create_if_missing,
     883                 :            :                                    const int option )
     884                 :            : {
     885                 :            :   ErrorCode rval;
     886                 :            :   const std::vector<EntityHandle> *vtx_adj, *vtx2_adj;
     887                 :            :   std::vector<EntityHandle> duplicates;
     888                 :            : 
     889                 :            :     // Handle ranges
     890                 :            :   const size_t in_size = target_entities.size();
     891                 :            :   const EntityType src_type = TYPE_FROM_HANDLE(source_entity);
     892                 :            :   DimensionPair target_types = CN::TypeDimensionMap[target_dimension];
     893                 :            :   const EntityHandle src_beg_handle = CREATE_HANDLE( src_type, 0 );
     894                 :            :   const EntityHandle src_end_handle = CREATE_HANDLE( src_type+1, 0 );
     895                 :            :   const EntityHandle tgt_beg_handle = CREATE_HANDLE( target_types.first, 0 );
     896                 :            :   const EntityHandle tgt_end_handle = CREATE_HANDLE( target_types.second+1, 0 );
     897                 :            : 
     898                 :            :     // get vertices
     899                 :            :   assert(TYPE_FROM_HANDLE(source_entity) != MBPOLYHEDRON); // can't go up from a region
     900                 :            :   std::vector<EntityHandle> conn_storage;
     901                 :            :   const EntityHandle* conn;
     902                 :            :   int conn_len;
     903                 :            :   rval = thisMB->get_connectivity( source_entity, conn, conn_len, true, &conn_storage );
     904                 :            :   if (MB_SUCCESS != rval)
     905                 :            :     return rval;
     906                 :            : 
     907                 :            :     // shouldn't be here if source entity is not an element
     908                 :            :   assert(conn_len > 1);
     909                 :            : 
     910                 :            :     // create necessary entities. this only makes sense if there exists of a
     911                 :            :     // dimension greater than the target dimension.
     912                 :            :   if (create_if_missing && target_dimension < 3 && CN::Dimension(src_type) < 2) {
     913                 :            :     for (size_t i = 0; i < conn_len; ++i) {
     914                 :            :       rval = get_adjacency_ptr( conn[i], vtx_adj );
     915                 :            :       if (MB_SUCCESS != rval)
     916                 :            :         return rval;
     917                 :            :       assert(vtx_adj != NULL); // should contain at least source_entity
     918                 :            : 
     919                 :            :       std::vector<EntityHandle> tmp2, tmp(*vtx_adj); // copy in case adjacency vector is changed
     920                 :            :       for (size_t j = 0; j < tmp.size(); ++j) {
     921                 :            :         if (CN::Dimension(TYPE_FROM_HANDLE(tmp[j])) <= (int)target_dimension)
     922                 :            :           continue;
     923                 :            :         if (TYPE_FROM_HANDLE(tmp[j]) == MBENTITYSET)
     924                 :            :           break;
     925                 :            : 
     926                 :            :         tmp2.clear();
     927                 :            :         rval = get_down_adjacency_elements( tmp[j], target_dimension, tmp2, true, option );
     928                 :            :         if (MB_SUCCESS != rval)
     929                 :            :           return rval;
     930                 :            :       }
     931                 :            :     }
     932                 :            :   }
     933                 :            : 
     934                 :            :     // get elements adjacent to first vertex
     935                 :            :   rval = get_adjacency_ptr( conn[0], vtx_adj );
     936                 :            :   if (MB_SUCCESS != rval)
     937                 :            :     return rval;
     938                 :            :   assert(vtx_adj != NULL); // should contain at least source_entity
     939                 :            :     // get elements adjacent to second vertex
     940                 :            :   rval = get_adjacency_ptr( conn[1], vtx2_adj );
     941                 :            :   if (MB_SUCCESS != rval)
     942                 :            :     return rval;
     943                 :            :   assert(vtx2_adj != NULL);
     944                 :            : 
     945                 :            :     // Put intersect of all entities except source entity with
     946                 :            :     // the same type as the source entity in 'duplicates'
     947                 :            :   std::vector<EntityHandle>::const_iterator it1, it2, end1, end2;
     948                 :            :   it1 = std::lower_bound( vtx_adj->begin(), vtx_adj->end(), src_beg_handle );
     949                 :            :   it2 = std::lower_bound( vtx2_adj->begin(), vtx2_adj->end(), src_beg_handle );
     950                 :            :   end1 = std::lower_bound( it1, vtx_adj->end(), src_end_handle );
     951                 :            :   end2 = std::lower_bound( it2, vtx2_adj->end(), src_end_handle );
     952                 :            :   assert(end1 != it1); // should at least contain source entity
     953                 :            :   duplicates.resize( end1 - it1 - 1 );
     954                 :            :   std::vector<EntityHandle>::iterator ins = duplicates.begin();
     955                 :            :   for (; it1 != end1; ++it1) {
     956                 :            :     if (*it1 != source_entity) {
     957                 :            :       *ins = *it1;
     958                 :            :       ++ins;
     959                 :            :     }
     960                 :            :   }
     961                 :            :   duplicates.erase( intersect( duplicates.begin(), duplicates.end(), it2, end2 ), duplicates.end() );
     962                 :            : 
     963                 :            :     // Append to input list any entities of the desired target dimension
     964                 :            :   it1 = std::lower_bound( end1, vtx_adj->end(), tgt_beg_handle );
     965                 :            :   it2 = std::lower_bound( end2, vtx2_adj->end(), tgt_beg_handle );
     966                 :            :   end1 = std::lower_bound( it1, vtx_adj->end(), tgt_end_handle );
     967                 :            :   end2 = std::lower_bound( it2, vtx2_adj->end(), tgt_end_handle );
     968                 :            :   std::set_intersection( it1, end1, it2, end2, std::back_inserter( target_entities ) );
     969                 :            : 
     970                 :            :     // for each additional vertex
     971                 :            :   for (int i = 2; i < conn_len; ++i) {
     972                 :            :     rval = get_adjacency_ptr( conn[i], vtx_adj );
     973                 :            :     if (MB_SUCCESS != rval)
     974                 :            :       return rval;
     975                 :            :     assert(vtx_adj != NULL); // should contain at least source_entity
     976                 :            : 
     977                 :            :     it1 = std::lower_bound( vtx_adj->begin(), vtx_adj->end(), src_beg_handle );
     978                 :            :     end1 = std::lower_bound( it1, vtx_adj->end(), src_end_handle );
     979                 :            :     duplicates.erase( intersect( duplicates.begin(), duplicates.end(), it1, end1 ), duplicates.end() );
     980                 :            : 
     981                 :            :     it1 = std::lower_bound( end1, vtx_adj->end(), tgt_beg_handle );
     982                 :            :     end1 = std::lower_bound( it1, vtx_adj->end(), tgt_end_handle );
     983                 :            :     target_entities.erase( intersect( target_entities.begin()+in_size, target_entities.end(),
     984                 :            :                            it1, end1 ), target_entities.end() );
     985                 :            :   }
     986                 :            : 
     987                 :            :     // if no duplicates, we're done
     988                 :            :   if (duplicates.empty())
     989                 :            :     return MB_SUCCESS;
     990                 :            : 
     991                 :            :     // Check for explicit adjacencies.  If an explicit adjacency
     992                 :            :     // connects candidate target entity to an entity equivalent
     993                 :            :     // to the source entity, then assume that source entity is *not*
     994                 :            :     // adjacent
     995                 :            :   const std::vector<EntityHandle>* adj_ptr;
     996                 :            :     // check adjacencies from duplicate entities to candidate targets
     997                 :            :   for (size_t i = 0; i < duplicates.size(); ++i) {
     998                 :            :     rval = get_adjacency_ptr( duplicates[i], adj_ptr );
     999                 :            :     if (MB_SUCCESS != rval)
    1000                 :            :       return rval;
    1001                 :            :     if (!adj_ptr)
    1002                 :            :       continue;
    1003                 :            : 
    1004                 :            :     for (size_t j = 0; j < adj_ptr->size(); ++j) {
    1005                 :            :       std::vector<EntityHandle>::iterator k =
    1006                 :            :         std::find( target_entities.begin()+in_size, target_entities.end(), (*adj_ptr)[j] );
    1007                 :            :       if (k != target_entities.end())
    1008                 :            :         target_entities.erase(k);
    1009                 :            :     }
    1010                 :            :   }
    1011                 :            : 
    1012                 :            :   // If target dimension is 3 and source dimension is 1, also need to
    1013                 :            :   // check for explicit adjacencies to intermediate faces
    1014                 :            :   if (CN::Dimension(src_type) > 1 || target_dimension < 3)
    1015                 :            :     return MB_SUCCESS;
    1016                 :            : 
    1017                 :            :     // Get faces adjacent to each element and check for explict
    1018                 :            :     // adjacencies from duplicate entities to faces
    1019                 :            :   for (size_t i = 0; i < duplicates.size(); ++i) {
    1020                 :            :     rval = get_adjacency_ptr( duplicates[i], adj_ptr );
    1021                 :            :     if (MB_SUCCESS != rval)
    1022                 :            :       return rval;
    1023                 :            :     if (!adj_ptr)
    1024                 :            :       continue;
    1025                 :            : 
    1026                 :            :     size_t j;
    1027                 :            :     for (j = 0; j < adj_ptr->size(); ++j) {
    1028                 :            :       const std::vector<EntityHandle>* adj_ptr2;
    1029                 :            :       rval = get_adjacency_ptr( (*adj_ptr)[j], adj_ptr2 );
    1030                 :            :       if (MB_SUCCESS != rval)
    1031                 :            :         return rval;
    1032                 :            :       if (!adj_ptr2)
    1033                 :            :         continue;
    1034                 :            : 
    1035                 :            :       for (size_t k = 0; k < adj_ptr2->size(); ++k) {
    1036                 :            :         std::vector<EntityHandle>::iterator it;
    1037                 :            :         it = std::find( target_entities.begin()+in_size, target_entities.end(), (*adj_ptr2)[k] );
    1038                 :            :         if (it != target_entities.end()) {
    1039                 :            :           target_entities.erase(it);
    1040                 :            :           j = adj_ptr->size(); // break outer loop
    1041                 :            :           break;
    1042                 :            :         }
    1043                 :            :       }
    1044                 :            :     }
    1045                 :            :   }
    1046                 :            : 
    1047                 :            :   return MB_SUCCESS;
    1048                 :            : }
    1049                 :            : #else
    1050                 :      55133 : ErrorCode AEntityFactory::get_up_adjacency_elements( EntityHandle source_entity, const unsigned int target_dimension,
    1051                 :            :                                                      std::vector< EntityHandle >& target_entities,
    1052                 :            :                                                      const bool create_if_missing,
    1053                 :            :                                                      const int /*create_adjacency_option = -1*/ )
    1054                 :            : {
    1055                 :            : 
    1056         [ +  - ]:      55133 :     EntityType source_type = TYPE_FROM_HANDLE( source_entity );
    1057                 :            : 
    1058                 :      55133 :     const EntityHandle* source_vertices = NULL;
    1059                 :      55133 :     int num_source_vertices             = 0;
    1060         [ +  - ]:      55133 :     std::vector< EntityHandle > conn_storage;
    1061                 :            : 
    1062                 :            :     // check to see whether there are any equivalent entities (same verts, different entity);
    1063                 :            :     // do this by calling get_element with a 0 source_entity, and look for a
    1064                 :            :     // MB_MULTIPLE_ENTITIES_FOUND return code
    1065                 :            : 
    1066                 :            :     // NOTE: we only want corner vertices here, and for the code below which also uses
    1067                 :            :     // source_vertices
    1068                 :            :     ErrorCode result =
    1069         [ +  - ]:      55133 :         thisMB->get_connectivity( source_entity, source_vertices, num_source_vertices, true, &conn_storage );
    1070         [ -  + ]:      55133 :     if( MB_SUCCESS != result ) return result;
    1071                 :            :     EntityHandle temp_entity;
    1072         [ +  - ]:      55133 :     result = get_element( source_vertices, num_source_vertices, source_type, temp_entity, false, 0 );
    1073                 :            : 
    1074                 :      55133 :     bool equiv_entities = ( result == MB_MULTIPLE_ENTITIES_FOUND ) ? true : false;
    1075                 :            : 
    1076         [ +  - ]:     110266 :     std::vector< EntityHandle > tmp_vec;
    1077         [ +  + ]:      55133 :     if( !equiv_entities )
    1078                 :            :     {
    1079                 :            :         // get elems adjacent to each node
    1080         [ +  - ]:      55080 :         std::vector< std::vector< EntityHandle > > elems( num_source_vertices );
    1081                 :            :         int i;
    1082         [ +  + ]:     167798 :         for( i = 0; i < num_source_vertices; i++ )
    1083                 :            :         {
    1084                 :            :             // get elements
    1085                 :            :             // see comment above pertaining to source_vertices; these are corner vertices only
    1086 [ +  - ][ +  - ]:     112718 :             get_zero_to_n_elements( source_vertices[i], target_dimension, elems[i], create_if_missing, 0 );
    1087                 :            :             // sort this element list
    1088 [ +  - ][ +  - ]:     112718 :             std::sort( elems[i].begin(), elems[i].end() );
                 [ +  - ]
    1089                 :            :         }
    1090                 :            : 
    1091                 :            :         // perform an intersection between all the element lists
    1092                 :            :         // see comment above pertaining to source_vertices; these are corner vertices only
    1093         [ +  + ]:     112718 :         for( i = 1; i < num_source_vertices; i++ )
    1094                 :            :         {
    1095                 :      57638 :             tmp_vec.clear();
    1096                 :            : 
    1097                 :            :             // intersection between first list and ith list, put result in tmp
    1098   [ +  -  +  -  :     230552 :             std::set_intersection( elems[0].begin(), elems[0].end(), elems[i].begin(), elems[i].end(),
             +  -  +  - ]
    1099 [ +  - ][ +  - ]:     288190 :                                    std::back_insert_iterator< std::vector< EntityHandle > >( tmp_vec ) );
    1100                 :            :             // tmp has elems[0] contents and elems[0] contents has tmp's contents
    1101                 :            :             // so that elems[0] always has the intersection of previous operations
    1102         [ +  - ]:      57638 :             elems[0].swap( tmp_vec );
    1103                 :            :         }
    1104                 :            : 
    1105                 :            :         // elems[0] contains the intersection, swap with target_entities
    1106 [ +  - ][ +  - ]:      55080 :         target_entities.insert( target_entities.end(), elems[0].begin(), elems[0].end() );
                 [ +  - ]
    1107                 :            :     }
    1108         [ +  + ]:         53 :     else if( source_type == MBPOLYGON )
    1109                 :            :     {
    1110                 :            :         // get adjacencies using polyhedra's connectivity vectors
    1111                 :            :         // first get polyhedra neighboring vertices
    1112         [ +  - ]:          2 :         result = thisMB->get_adjacencies( source_vertices, num_source_vertices, 3, false, tmp_vec );
    1113         [ -  + ]:          2 :         if( MB_SUCCESS != result ) return result;
    1114                 :            : 
    1115                 :            :         // now filter according to whether each is adjacent to the polygon
    1116                 :          2 :         const EntityHandle* connect = NULL;
    1117                 :          2 :         int num_connect             = 0;
    1118         [ +  - ]:          2 :         std::vector< EntityHandle > storage;
    1119 [ -  + ][ +  - ]:          2 :         for( unsigned int i = 0; i < tmp_vec.size(); i++ )
    1120                 :            :         {
    1121 [ #  # ][ #  # ]:          0 :             result = thisMB->get_connectivity( tmp_vec[i], connect, num_connect, false, &storage );
    1122         [ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
    1123 [ #  # ][ #  # ]:          0 :             if( std::find( connect, connect + num_connect, source_entity ) != connect + num_connect )
    1124 [ #  # ][ #  # ]:          0 :                 target_entities.push_back( tmp_vec[i] );
    1125                 :          2 :         }
    1126                 :            :     }
    1127                 :            : 
    1128                 :            :     else
    1129                 :            :     {
    1130                 :            :         // else get up-adjacencies directly; code copied from get_zero_to_n_elements
    1131                 :            : 
    1132                 :            :         // get the adjacency vector
    1133                 :         51 :         AdjacencyVector* adj_vec = NULL;
    1134         [ +  - ]:         51 :         result                   = get_adjacencies( source_entity, adj_vec );
    1135                 :            : 
    1136         [ -  + ]:         51 :         if( result != MB_SUCCESS )
    1137                 :         50 :             return result;
    1138         [ +  + ]:         51 :         else if( adj_vec == NULL )
    1139                 :         50 :             return MB_SUCCESS;
    1140                 :            : 
    1141         [ +  - ]:          1 :         DimensionPair dim_pair_dp1 = CN::TypeDimensionMap[CN::Dimension( source_type ) + 1],
    1142                 :          1 :                       dim_pair_td  = CN::TypeDimensionMap[target_dimension];
    1143                 :            :         int dum;
    1144                 :            : 
    1145 [ +  - ][ +  - ]:          2 :         Range tmp_ents, target_ents;
                 [ +  - ]
    1146                 :            : 
    1147                 :            :         // get iterators for start handle of source_dim+1 and target_dim, and end handle
    1148                 :            :         // of target_dim
    1149                 :            :         AdjacencyVector::iterator start_ent_dp1 =
    1150                 :            :                                       std::lower_bound( adj_vec->begin(), adj_vec->end(),
    1151 [ +  - ][ +  - ]:          1 :                                                         CREATE_HANDLE( dim_pair_dp1.first, MB_START_ID, dum ) ),
    1152                 :            : 
    1153                 :            :                                   start_ent_td =
    1154                 :            :                                       std::lower_bound( adj_vec->begin(), adj_vec->end(),
    1155 [ +  - ][ +  - ]:          1 :                                                         CREATE_HANDLE( dim_pair_td.first, MB_START_ID, dum ) ),
    1156                 :            : 
    1157                 :            :                                   end_ent_td = std::lower_bound( adj_vec->begin(), adj_vec->end(),
    1158 [ +  - ][ +  - ]:          1 :                                                                  CREATE_HANDLE( dim_pair_td.second, MB_END_ID, dum ) );
    1159                 :            : 
    1160                 :            :         // get the adjacencies for source_dim+1 to target_dim-1, and the adjacencies from
    1161                 :            :         // those to target_dim
    1162 [ +  - ][ +  - ]:          1 :         std::copy( start_ent_dp1, start_ent_td, range_inserter( tmp_ents ) );
    1163         [ +  - ]:          1 :         result = thisMB->get_adjacencies( tmp_ents, target_dimension, false, target_ents, Interface::UNION );
    1164         [ -  + ]:          1 :         if( MB_SUCCESS != result ) return result;
    1165                 :            : 
    1166                 :            :         // now copy the explicit adjacencies to target_dimension
    1167 [ +  - ][ +  - ]:          1 :         std::copy( start_ent_td, end_ent_td, range_inserter( target_ents ) );
    1168                 :            : 
    1169                 :            :         // now insert the whole thing into the argument vector
    1170                 :            : #ifdef MOAB_NO_VECTOR_TEMPLATE_INSERT
    1171                 :            :         std::copy( target_ents.begin(), target_ents.end(), std::back_inserter( target_entities ) );
    1172                 :            : #else
    1173 [ +  - ][ +  - ]:          2 :         target_entities.insert( target_entities.end(), target_ents.begin(), target_ents.end() );
         [ +  - ][ +  - ]
    1174                 :            : #endif
    1175                 :            :     }
    1176                 :            : 
    1177                 :     110216 :     return result;
    1178                 :            : }
    1179                 :            : #endif
    1180                 :            : 
    1181                 :       3747 : ErrorCode AEntityFactory::notify_change_connectivity( EntityHandle entity, const EntityHandle* old_array,
    1182                 :            :                                                       const EntityHandle* new_array, int number_verts )
    1183                 :            : {
    1184         [ +  - ]:       3747 :     EntityType source_type = TYPE_FROM_HANDLE( entity );
    1185         [ -  + ]:       3747 :     if( source_type == MBPOLYHEDRON ) return MB_NOT_IMPLEMENTED;
    1186                 :            : 
    1187                 :            :     // find out which ones to add and which to remove
    1188 [ +  - ][ +  - ]:       7494 :     std::vector< EntityHandle > old_verts, new_verts;
    1189                 :            :     int i;
    1190         [ +  + ]:      22609 :     for( i = 0; i < number_verts; i++ )
    1191                 :            :     {
    1192         [ +  + ]:      18862 :         if( old_array[i] != new_array[i] )
    1193                 :            :         {
    1194         [ +  - ]:      11331 :             old_verts.push_back( old_array[i] );
    1195         [ +  - ]:      11331 :             new_verts.push_back( new_array[i] );
    1196                 :            :         }
    1197                 :            :     }
    1198                 :            : 
    1199                 :            :     ErrorCode result;
    1200                 :            : 
    1201         [ +  + ]:       3747 :     if( mVertElemAdj == true )
    1202                 :            :     {
    1203                 :            :         // update the vertex-entity adjacencies
    1204                 :       1197 :         std::vector< EntityHandle >::iterator adj_iter;
    1205 [ +  - ][ +  - ]:       2488 :         for( adj_iter = old_verts.begin(); adj_iter != old_verts.end(); ++adj_iter )
                 [ +  + ]
    1206                 :            :         {
    1207 [ +  - ][ +  - ]:       1291 :             if( std::find( new_verts.begin(), new_verts.end(), *adj_iter ) == new_verts.end() )
         [ +  - ][ +  + ]
    1208                 :            :             {
    1209 [ +  - ][ +  - ]:       1287 :                 result = remove_adjacency( *adj_iter, entity );
    1210         [ -  + ]:       1287 :                 if( MB_SUCCESS != result ) return result;
    1211                 :            :             }
    1212                 :            :         }
    1213 [ +  - ][ +  - ]:       2488 :         for( adj_iter = new_verts.begin(); adj_iter != new_verts.end(); ++adj_iter )
                 [ +  + ]
    1214                 :            :         {
    1215 [ +  - ][ +  - ]:       1291 :             if( std::find( old_verts.begin(), old_verts.end(), *adj_iter ) == old_verts.end() )
         [ +  - ][ +  + ]
    1216                 :            :             {
    1217 [ +  - ][ +  - ]:       1287 :                 result = add_adjacency( *adj_iter, entity );
    1218         [ -  + ]:       1287 :                 if( MB_SUCCESS != result ) return result;
    1219                 :            :             }
    1220                 :            :         }
    1221                 :            :     }
    1222                 :            : 
    1223                 :       7494 :     return MB_SUCCESS;
    1224                 :            : }
    1225                 :            : 
    1226                 :            : //! return true if 2 entities are explicitly adjacent
    1227                 :    1510373 : bool AEntityFactory::explicitly_adjacent( const EntityHandle ent1, const EntityHandle ent2 )
    1228                 :            : {
    1229                 :            :     const EntityHandle* explicit_adjs;
    1230                 :            :     int num_exp;
    1231         [ +  - ]:    1510373 :     get_adjacencies( ent1, explicit_adjs, num_exp );
    1232 [ +  - ][ -  + ]:    1510373 :     if( std::find( explicit_adjs, explicit_adjs + num_exp, ent2 ) != explicit_adjs + num_exp )
    1233                 :          0 :         return true;
    1234                 :            :     else
    1235                 :    1510373 :         return false;
    1236                 :            : }
    1237                 :            : 
    1238                 :        442 : ErrorCode AEntityFactory::merge_adjust_adjacencies( EntityHandle entity_to_keep, EntityHandle entity_to_remove )
    1239                 :            : {
    1240 [ +  - ][ +  - ]:        442 :     int ent_dim = CN::Dimension( TYPE_FROM_HANDLE( entity_to_keep ) );
    1241                 :            :     ErrorCode result;
    1242                 :            : 
    1243                 :            :     // check for newly-formed equivalent entities, and create explicit adjacencies
    1244                 :            :     // to distinguish them; this must be done before connectivity of higher-dimensional
    1245                 :            :     // entities is changed below, and only needs to be checked if merging vertices
    1246         [ +  + ]:        442 :     if( ent_dim == 0 )
    1247                 :            :     {
    1248         [ +  - ]:        411 :         result = check_equiv_entities( entity_to_keep, entity_to_remove );
    1249         [ -  + ]:        411 :         if( MB_SUCCESS != result ) return result;
    1250                 :            :     }
    1251                 :            : 
    1252                 :            :     // check adjacencies TO removed entity
    1253         [ +  + ]:        472 :     for( int dim = 1; dim < ent_dim; dim++ )
    1254                 :            :     {
    1255         [ +  - ]:         30 :         Range adjs;
    1256         [ +  - ]:         30 :         result = thisMB->get_adjacencies( &entity_to_remove, 1, dim, false, adjs );
    1257         [ -  + ]:         30 :         if( result != MB_SUCCESS ) return result;
    1258                 :            :         // for any explicit ones, make them adjacent to keeper
    1259 [ +  - ][ #  # ]:         30 :         for( Range::iterator rit = adjs.begin(); rit != adjs.end(); ++rit )
         [ +  - ][ +  - ]
         [ -  + ][ +  - ]
    1260                 :            :         {
    1261 [ #  # ][ #  # ]:          0 :             if( this->explicitly_adjacent( *rit, entity_to_remove ) )
                 [ #  # ]
    1262                 :            :             {
    1263 [ #  # ][ #  # ]:          0 :                 result = this->add_adjacency( *rit, entity_to_keep );
    1264         [ #  # ]:          0 :                 if( result != MB_SUCCESS ) return result;
    1265                 :            :             }
    1266                 :            :         }
    1267                 :         30 :     }
    1268                 :            : 
    1269                 :            :     // check adjacencies FROM removed entity
    1270 [ +  - ][ +  - ]:        884 :     std::vector< EntityHandle > conn, adjs;
    1271         [ +  - ]:        442 :     result = this->get_adjacencies( entity_to_remove, adjs );
    1272         [ -  + ]:        442 :     if( result != MB_SUCCESS ) return result;
    1273                 :            :     // set them all, and if to_entity is a set, add to that one too
    1274         [ +  + ]:       1605 :     for( unsigned int i = 0; i < adjs.size(); i++ )
    1275                 :            :     {
    1276 [ +  - ][ +  - ]:       1163 :         if( TYPE_FROM_HANDLE( adjs[i] ) == MBENTITYSET )
                 [ +  + ]
    1277                 :            :         {
    1278                 :            :             // result = this->add_adjacency(entity_to_keep, adjs[i]);
    1279                 :            :             // if(result != MB_SUCCESS) return result;
    1280                 :            :             // result = thisMB->add_entities(adjs[i], &entity_to_keep, 1);
    1281                 :            :             // if(result != MB_SUCCESS) return result;
    1282 [ +  - ][ +  - ]:          3 :             result = thisMB->replace_entities( adjs[i], &entity_to_remove, &entity_to_keep, 1 );
    1283         [ -  + ]:          3 :             if( MB_SUCCESS != result ) return result;
    1284                 :            :         }
    1285         [ +  + ]:       1160 :         else if( ent_dim == 0 )
    1286                 :            :         {
    1287                 :       1159 :             conn.clear();
    1288 [ +  - ][ +  - ]:       1159 :             result = thisMB->get_connectivity( &adjs[i], 1, conn );
    1289                 :            : 
    1290         [ +  - ]:       1159 :             if( result == MB_SUCCESS )
    1291                 :            :             {
    1292         [ +  - ]:       1159 :                 std::replace( conn.begin(), conn.end(), entity_to_remove, entity_to_keep );
    1293 [ +  - ][ +  - ]:       1159 :                 result = thisMB->set_connectivity( adjs[i], &conn[0], conn.size() );
                 [ +  - ]
    1294         [ -  + ]:       1159 :                 if( MB_SUCCESS != result ) return result;
    1295                 :            :             }
    1296                 :            :             else
    1297                 :          0 :                 return result;
    1298                 :            :         }
    1299                 :            :         else
    1300                 :            :         {
    1301 [ +  - ][ +  - ]:          1 :             result = this->add_adjacency( entity_to_keep, adjs[i] );
    1302         [ -  + ]:          1 :             if( result != MB_SUCCESS ) return result;
    1303                 :            :         }
    1304                 :            :     }
    1305                 :            : 
    1306                 :        884 :     return MB_SUCCESS;
    1307                 :            : }
    1308                 :            : 
    1309                 :            : // check for equivalent entities that may be formed when merging two entities, and
    1310                 :            : // create explicit adjacencies accordingly
    1311                 :        411 : ErrorCode AEntityFactory::check_equiv_entities( EntityHandle entity_to_keep, EntityHandle entity_to_remove )
    1312                 :            : {
    1313 [ +  - ][ -  + ]:        411 :     if( thisMB->dimension_from_handle( entity_to_keep ) > 0 ) return MB_SUCCESS;
    1314                 :            : 
    1315                 :            :     // get all the adjacencies for both entities for all dimensions > 0
    1316 [ +  - ][ +  - ]:        822 :     Range adjs_keep, adjs_remove;
    1317                 :            :     ErrorCode result;
    1318                 :            : 
    1319         [ +  + ]:       1644 :     for( int dim = 1; dim <= 3; dim++ )
    1320                 :            :     {
    1321         [ +  - ]:       1233 :         result = thisMB->get_adjacencies( &entity_to_keep, 1, dim, false, adjs_keep, Interface::UNION );
    1322         [ -  + ]:       1233 :         if( MB_SUCCESS != result ) return result;
    1323         [ +  - ]:       1233 :         result = thisMB->get_adjacencies( &entity_to_remove, 1, dim, false, adjs_remove, Interface::UNION );
    1324         [ -  + ]:       1233 :         if( MB_SUCCESS != result ) return result;
    1325                 :            :     }
    1326                 :            : 
    1327                 :            :     // now look for equiv entities which will be formed
    1328                 :            :     // algorithm:
    1329                 :            :     // for each entity adjacent to removed entity:
    1330                 :            :     EntityHandle two_ents[2];
    1331 [ +  - ][ +  - ]:       1570 :     for( Range::iterator rit_rm = adjs_remove.begin(); rit_rm != adjs_remove.end(); ++rit_rm )
         [ +  - ][ +  - ]
                 [ +  + ]
    1332                 :            :     {
    1333         [ +  - ]:       1159 :         two_ents[0] = *rit_rm;
    1334                 :            : 
    1335                 :            :         // - for each entity of same dimension adjacent to kept entity:
    1336 [ +  - ][ +  - ]:       5829 :         for( Range::iterator rit_kp = adjs_keep.begin(); rit_kp != adjs_keep.end(); ++rit_kp )
         [ +  - ][ +  - ]
                 [ +  + ]
    1337                 :            :         {
    1338 [ +  - ][ +  - ]:       9036 :             if( TYPE_FROM_HANDLE( *rit_kp ) != TYPE_FROM_HANDLE( *rit_rm ) ) continue;
         [ +  - ][ +  - ]
                 [ +  + ]
    1339                 :            : 
    1340         [ +  - ]:       4434 :             Range all_verts;
    1341         [ +  - ]:       4434 :             two_ents[1] = *rit_kp;
    1342                 :            :             //   . get union of adjacent vertices to two entities
    1343         [ +  - ]:       4434 :             result = thisMB->get_adjacencies( two_ents, 2, 0, false, all_verts, Interface::UNION );
    1344         [ -  + ]:       4434 :             if( MB_SUCCESS != result ) return result;
    1345                 :            : 
    1346 [ +  - ][ +  - ]:      13302 :             assert( all_verts.find( entity_to_keep ) != all_verts.end() &&
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ #  #  
          #  #  #  #  #  
                      # ]
    1347         [ +  - ]:       8868 :                     all_verts.find( entity_to_remove ) != all_verts.end() );
    1348                 :            : 
    1349                 :            :             //   . if # vertices != number of corner vertices + 1, continue
    1350 [ +  - ][ +  - ]:       4434 :             if( CN::VerticesPerEntity( TYPE_FROM_HANDLE( *rit_rm ) ) + 1 != (int)all_verts.size() ) continue;
         [ +  - ][ +  - ]
                 [ +  + ]
    1351                 :            : 
    1352                 :            :             //   . for the two entities adjacent to kept & removed entity:
    1353 [ +  - ][ +  - ]:         68 :             result = create_explicit_adjs( *rit_rm );
    1354         [ -  + ]:         68 :             if( MB_SUCCESS != result ) return result;
    1355 [ +  - ][ +  - ]:         68 :             result = create_explicit_adjs( *rit_kp );
    1356         [ -  + ]:       4434 :             if( MB_SUCCESS != result ) return result;
              [ +  +  - ]
    1357                 :            :             //   . (end for)
    1358                 :         68 :         }
    1359                 :            :         // - (end for)
    1360                 :            :     }
    1361                 :            : 
    1362                 :        822 :     return MB_SUCCESS;
    1363                 :            : }
    1364                 :            : 
    1365                 :        136 : ErrorCode AEntityFactory::create_explicit_adjs( EntityHandle this_ent )
    1366                 :            : {
    1367                 :            :     //     - get adjacent entities of next higher dimension
    1368         [ +  - ]:        136 :     Range all_adjs;
    1369                 :            :     ErrorCode result;
    1370         [ +  - ]:        136 :     result = thisMB->get_adjacencies( &this_ent, 1, thisMB->dimension_from_handle( this_ent ) + 1, false, all_adjs,
    1371         [ +  - ]:        136 :                                       Interface::UNION );
    1372         [ -  + ]:        136 :     if( MB_SUCCESS != result ) return result;
    1373                 :            : 
    1374                 :            :     //     - create explicit adjacency to these entities
    1375 [ +  - ][ +  - ]:        152 :     for( Range::iterator rit = all_adjs.begin(); rit != all_adjs.end(); ++rit )
         [ +  - ][ +  - ]
                 [ +  + ]
    1376                 :            :     {
    1377 [ +  - ][ +  - ]:         16 :         result = add_adjacency( this_ent, *rit );
    1378         [ -  + ]:         16 :         if( MB_SUCCESS != result ) return result;
    1379                 :            :     }
    1380                 :            : 
    1381                 :        136 :     return MB_SUCCESS;
    1382                 :            : }
    1383                 :            : 
    1384                 :    2924342 : ErrorCode AEntityFactory::get_adjacency_ptr( EntityHandle entity, std::vector< EntityHandle >*& ptr )
    1385                 :            : {
    1386                 :    2924342 :     ptr = 0;
    1387                 :            : 
    1388                 :            :     EntitySequence* seq;
    1389 [ +  - ][ +  - ]:    2924342 :     ErrorCode rval = thisMB->sequence_manager()->find( entity, seq );
    1390 [ +  + ][ +  - ]:    2924342 :     if( MB_SUCCESS != rval || !seq->data()->get_adjacency_data() ) return rval;
         [ +  - ][ +  + ]
                 [ +  + ]
    1391                 :            : 
    1392 [ +  - ][ +  - ]:    2899245 :     ptr = seq->data()->get_adjacency_data()[entity - seq->data()->start_handle()];
         [ +  - ][ +  - ]
    1393                 :    2924342 :     return MB_SUCCESS;
    1394                 :            : }
    1395                 :            : 
    1396                 :    2642125 : ErrorCode AEntityFactory::get_adjacency_ptr( EntityHandle entity, const std::vector< EntityHandle >*& ptr ) const
    1397                 :            : {
    1398                 :    2642125 :     ptr = 0;
    1399                 :            : 
    1400                 :            :     EntitySequence* seq;
    1401 [ +  - ][ +  - ]:    2642125 :     ErrorCode rval = thisMB->sequence_manager()->find( entity, seq );
    1402 [ +  - ][ +  - ]:    2642125 :     if( MB_SUCCESS != rval || !seq->data()->get_adjacency_data() ) return rval;
         [ +  - ][ +  + ]
                 [ +  + ]
    1403                 :            : 
    1404 [ +  - ][ +  - ]:     974140 :     ptr = seq->data()->get_adjacency_data()[entity - seq->data()->start_handle()];
         [ +  - ][ +  - ]
    1405                 :    2642125 :     return MB_SUCCESS;
    1406                 :            : }
    1407                 :            : 
    1408                 :     356853 : ErrorCode AEntityFactory::set_adjacency_ptr( EntityHandle entity, std::vector< EntityHandle >* ptr )
    1409                 :            : {
    1410                 :            :     EntitySequence* seq;
    1411 [ +  - ][ +  - ]:     356853 :     ErrorCode rval = thisMB->sequence_manager()->find( entity, seq );
    1412         [ -  + ]:     356853 :     if( MB_SUCCESS != rval ) return rval;
    1413                 :            : 
    1414 [ +  - ][ +  - ]:     356853 :     if( !seq->data()->get_adjacency_data() && !seq->data()->allocate_adjacency_data() )
         [ +  + ][ +  - ]
         [ +  - ][ -  + ]
                 [ -  + ]
    1415                 :          0 :         return MB_MEMORY_ALLOCATION_FAILED;
    1416                 :            : 
    1417 [ +  - ][ +  - ]:     356853 :     const EntityHandle index          = entity - seq->data()->start_handle();
    1418 [ +  - ][ +  - ]:     356853 :     std::vector< EntityHandle >*& ref = seq->data()->get_adjacency_data()[index];
    1419         [ +  + ]:     356853 :     delete ref;
    1420                 :     356853 :     ref = ptr;
    1421                 :     356853 :     return MB_SUCCESS;
    1422                 :            : }
    1423                 :            : 
    1424                 :          4 : void AEntityFactory::get_memory_use( unsigned long long& entity_total, unsigned long long& memory_total )
    1425                 :            : {
    1426                 :          4 :     entity_total = memory_total = 0;
    1427                 :            : 
    1428                 :            :     // iterate through each element type
    1429                 :          4 :     SequenceData* prev_data = 0;
    1430 [ +  - ][ +  + ]:         48 :     for( EntityType t = MBVERTEX; t != MBENTITYSET; t++ )
    1431                 :            :     {
    1432         [ +  - ]:         44 :         TypeSequenceManager::iterator i;
    1433 [ +  - ][ +  - ]:         44 :         TypeSequenceManager& seqman = thisMB->sequence_manager()->entity_map( t );
    1434 [ +  - ][ +  - ]:         50 :         for( i = seqman.begin(); i != seqman.end(); ++i )
         [ +  - ][ +  - ]
                 [ +  + ]
    1435                 :            :         {
    1436 [ +  - ][ +  - ]:          6 :             if( !( *i )->data()->get_adjacency_data() ) continue;
         [ +  - ][ +  - ]
    1437                 :            : 
    1438 [ #  # ][ #  # ]:          0 :             if( prev_data != ( *i )->data() )
                 [ #  # ]
    1439                 :            :             {
    1440 [ #  # ][ #  # ]:          0 :                 prev_data = ( *i )->data();
    1441         [ #  # ]:          0 :                 memory_total += prev_data->size() * sizeof( AdjacencyVector* );
    1442                 :            :             }
    1443                 :            : 
    1444                 :            :             const AdjacencyVector* vec;
    1445 [ #  # ][ #  # ]:          0 :             for( EntityHandle h = ( *i )->start_handle(); h <= ( *i )->end_handle(); ++h )
         [ #  # ][ #  # ]
                 [ #  # ]
    1446                 :            :             {
    1447         [ #  # ]:          0 :                 get_adjacency_ptr( h, vec );
    1448         [ #  # ]:          0 :                 if( vec ) entity_total += vec->capacity() * sizeof( EntityHandle ) + sizeof( AdjacencyVector );
    1449                 :            :             }
    1450                 :            :         }
    1451                 :            :     }
    1452                 :            : 
    1453                 :          4 :     memory_total += sizeof( *this ) + entity_total;
    1454                 :          4 : }
    1455                 :            : 
    1456                 :          4 : ErrorCode AEntityFactory::get_memory_use( const Range& ents_in, unsigned long long& min_per_ent,
    1457                 :            :                                           unsigned long long& amortized )
    1458                 :            : {
    1459                 :          4 :     min_per_ent = amortized = 0;
    1460                 :          4 :     SequenceData* prev_data = 0;
    1461 [ +  - ][ +  - ]:          4 :     RangeSeqIntersectIter iter( thisMB->sequence_manager() );
    1462 [ +  - ][ +  - ]:          4 :     ErrorCode rval = iter.init( ents_in.begin(), ents_in.end() );
                 [ +  - ]
    1463         [ -  + ]:          4 :     if( MB_SUCCESS != rval ) return rval;
    1464                 :            : 
    1465 [ +  - ][ -  + ]:          4 :     do
    1466                 :            :     {
    1467 [ +  - ][ +  - ]:          4 :         AdjacencyVector** array = iter.get_sequence()->data()->get_adjacency_data();
                 [ +  - ]
    1468         [ +  - ]:          4 :         if( !array ) continue;
    1469                 :            : 
    1470 [ #  # ][ #  # ]:          0 :         EntityID count    = iter.get_end_handle() - iter.get_start_handle() + 1;
    1471                 :            :         EntityID data_occ = thisMB->sequence_manager()
    1472 [ #  # ][ #  # ]:          0 :                                 ->entity_map( iter.get_sequence()->type() )
         [ #  # ][ #  # ]
    1473 [ #  # ][ #  # ]:          0 :                                 .get_occupied_size( iter.get_sequence()->data() );
                 [ #  # ]
    1474                 :            : 
    1475 [ #  # ][ #  # ]:          0 :         if( iter.get_sequence()->data() != prev_data )
                 [ #  # ]
    1476                 :            :         {
    1477 [ #  # ][ #  # ]:          0 :             prev_data = iter.get_sequence()->data();
    1478 [ #  # ][ #  # ]:          0 :             amortized += sizeof( AdjacencyVector* ) * iter.get_sequence()->data()->size() * count / data_occ;
                 [ #  # ]
    1479                 :            :         }
    1480                 :            : 
    1481 [ #  # ][ #  # ]:          0 :         array += iter.get_start_handle() - iter.get_sequence()->data()->start_handle();
         [ #  # ][ #  # ]
    1482         [ #  # ]:          0 :         for( EntityID i = 0; i < count; ++i )
    1483                 :            :         {
    1484         [ #  # ]:          0 :             if( array[i] ) min_per_ent += sizeof( EntityHandle ) * array[i]->capacity() + sizeof( AdjacencyVector );
    1485                 :            :         }
    1486                 :            :     } while( MB_SUCCESS == ( rval = iter.step() ) );
    1487                 :            : 
    1488                 :          4 :     amortized += min_per_ent;
    1489         [ -  + ]:          4 :     return ( rval == MB_FAILURE ) ? MB_SUCCESS : rval;
    1490                 :            : }
    1491                 :            : 
    1492                 :            : /*!
    1493                 :            :    calling code is notifying this that an entity is going to be deleted
    1494                 :            :    from the database
    1495                 :            : */
    1496                 :      53857 : ErrorCode AEntityFactory::notify_delete_entity( EntityHandle entity )
    1497                 :            : {
    1498         [ +  + ]:      53857 :     if( TYPE_FROM_HANDLE( entity ) == MBVERTEX )
    1499                 :            :     {
    1500         [ +  - ]:        724 :         std::vector< EntityHandle > adj_entities;
    1501 [ +  + ][ +  - ]:       2896 :         for( int dim = 1; dim < 4; ++dim )
    1502                 :            :         {
    1503         [ +  - ]:       2172 :             ErrorCode rval = get_adjacencies( entity, dim, false, adj_entities );
    1504 [ +  + ][ -  + ]:       2172 :             if( rval != MB_SUCCESS && rval != MB_ENTITY_NOT_FOUND ) return rval;
    1505         [ -  + ]:       2172 :             if( !adj_entities.empty() ) return MB_FAILURE;
    1506                 :        724 :         }
    1507                 :            :     }
    1508                 :            : 
    1509                 :            :     // remove any references to this entity from other entities
    1510                 :      53857 :     return remove_all_adjacencies( entity, true );
    1511                 :            : }
    1512                 :            : 
    1513 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11