LCOV - code coverage report
Current view: top level - src - BoundBox.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 31 77 40.3 %
Date: 2020-12-16 07:07:30 Functions: 3 4 75.0 %
Branches: 49 188 26.1 %

           Branch data     Line data    Source code
       1                 :            : #include "moab/Interface.hpp"
       2                 :            : #include "moab/BoundBox.hpp"
       3                 :            : 
       4                 :            : // this is used for spherical elements, bounding box needs to be updated due to curvature
       5                 :            : #include "moab/IntxMesh/IntxUtils.hpp"
       6                 :            : 
       7                 :            : namespace moab
       8                 :            : {
       9                 :         22 : ErrorCode BoundBox::update( Interface& iface, const Range& elems, bool spherical, double radius )
      10                 :            : {
      11                 :            :     ErrorCode rval;
      12         [ +  - ]:         22 :     bMin = CartVect( HUGE_VAL );
      13         [ +  - ]:         22 :     bMax = CartVect( -HUGE_VAL );
      14                 :            : 
      15         [ +  - ]:         22 :     CartVect coords;
      16                 :         22 :     EntityHandle const *conn = NULL, *conn2 = NULL;
      17                 :         22 :     int len = 0, len2 = 0;
      18         [ +  - ]:         22 :     Range::const_iterator i;
      19 [ +  - ][ +  + ]:        616 :     CartVect coordverts[27];  // maximum nodes per element supported by MOAB
      20                 :            : 
      21                 :            :     // vertices
      22         [ +  - ]:         22 :     const Range::const_iterator elem_begin = elems.lower_bound( MBEDGE );
      23 [ +  - ][ +  - ]:        887 :     for( i = elems.begin(); i != elem_begin; ++i )
         [ +  - ][ +  + ]
      24                 :            :     {
      25 [ +  - ][ +  - ]:        865 :         rval = iface.get_coords( &*i, 1, coords.array() );
                 [ +  - ]
      26         [ -  + ]:        865 :         if( MB_SUCCESS != rval ) return rval;
      27 [ +  - ][ +  - ]:        865 :         update_min( coords.array() );
      28 [ +  - ][ +  - ]:        865 :         update_max( coords.array() );
      29                 :            :     }
      30                 :            : 
      31                 :            :     // elements with vertex-handle connectivity list
      32         [ +  - ]:         22 :     const Range::const_iterator poly_begin = elems.lower_bound( MBPOLYHEDRON, elem_begin );
      33         [ +  - ]:         22 :     std::vector< EntityHandle > dum_vector;
      34 [ +  - ][ +  - ]:       5595 :     for( i = elem_begin; i != poly_begin; ++i )
                 [ +  + ]
      35                 :            :     {
      36 [ +  - ][ +  - ]:       5573 :         rval = iface.get_connectivity( *i, conn, len, true, &dum_vector );
      37         [ -  + ]:       5573 :         if( MB_SUCCESS != rval ) return rval;
      38                 :            : 
      39 [ +  - ][ +  - ]:       5573 :         rval = iface.get_coords( conn, len, &( coordverts[0][0] ) );
      40         [ -  + ]:       5573 :         if( MB_SUCCESS != rval ) return rval;
      41         [ +  + ]:      35761 :         for( int j = 0; j < len; ++j )
      42                 :            :         {
      43 [ +  - ][ +  - ]:      30188 :             update_min( coordverts[j].array() );
      44 [ +  - ][ +  - ]:      30188 :             update_max( coordverts[j].array() );
      45                 :            :         }
      46                 :            :         // if spherical, use gnomonic projection to improve the computed box
      47                 :            :         // it is used now for coupling only
      48 [ -  + ][ #  # ]:       5573 :         if( spherical ) update_box_spherical_elem( coordverts, len, radius );
      49                 :            :     }
      50                 :            : 
      51                 :            :     // polyhedra
      52         [ +  - ]:         22 :     const Range::const_iterator set_begin = elems.lower_bound( MBENTITYSET, poly_begin );
      53 [ #  # ][ +  - ]:         22 :     for( i = poly_begin; i != set_begin; ++i )
                 [ -  + ]
      54                 :            :     {
      55 [ #  # ][ #  # ]:          0 :         rval = iface.get_connectivity( *i, conn, len, true );
      56         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return rval;
      57                 :            : 
      58         [ #  # ]:          0 :         for( int j = 0; j < len; ++j )
      59                 :            :         {
      60         [ #  # ]:          0 :             rval = iface.get_connectivity( conn[j], conn2, len2 );
      61         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
      62 [ #  # ][ #  # ]:          0 :             rval = iface.get_coords( conn2, len2, &( coordverts[0][0] ) );
      63         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
      64         [ #  # ]:          0 :             for( int k = 0; k < len2; ++k )
      65                 :            :             {
      66 [ #  # ][ #  # ]:          0 :                 update_min( coordverts[k].array() );
      67 [ #  # ][ #  # ]:          0 :                 update_max( coordverts[k].array() );
      68                 :            :             }
      69                 :            :         }
      70                 :            :     }
      71                 :            : 
      72                 :            :     // sets
      73         [ +  - ]:         44 :     BoundBox box;
      74 [ #  # ][ +  - ]:         22 :     for( i = set_begin; i != elems.end(); ++i )
         [ +  - ][ -  + ]
      75                 :            :     {
      76         [ #  # ]:          0 :         Range tmp_elems;
      77 [ #  # ][ #  # ]:          0 :         rval = iface.get_entities_by_handle( *i, tmp_elems );
      78         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return rval;
      79         [ #  # ]:          0 :         rval = box.update( iface, tmp_elems, spherical, radius );
      80         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return rval;
      81                 :            : 
      82 [ #  # ][ #  # ]:          0 :         update( box );
      83                 :          0 :     }
      84                 :            : 
      85                 :         44 :     return MB_SUCCESS;
      86                 :            : }
      87                 :          0 : void BoundBox::update_box_spherical_elem( const CartVect* verts, int len, double R )
      88                 :            : {
      89                 :            :     // decide first the gnomonic plane, based on first coordinate
      90                 :          0 :     int plane = -1;
      91         [ #  # ]:          0 :     CartVect pos;
      92         [ #  # ]:          0 :     IntxUtils::decide_gnomonic_plane( verts[0], plane );
      93                 :            :     double in_plane_positions[20];  // at most polygons with 10 edges; do we need to revise this?
      94 [ #  # ][ #  # ]:          0 :     for( int i = 0; i < len && i < 10; i++ )
      95         [ #  # ]:          0 :         IntxUtils::gnomonic_projection( verts[i], R, plane, in_plane_positions[2 * i], in_plane_positions[2 * i + 1] );
      96                 :            :     // look for points on the intersection between edges in gnomonic plane and coordinate axes
      97                 :            :     // if yes, reverse projection of intx point, and update box
      98                 :          0 :     double oriented_area2 = 0;
      99                 :            :     // if oriented area is != zero, it means the origin is inside the polygon, so we need to upgrade
     100                 :            :     // the box with the origin, so we do not miss anything (the top of the dome)
     101         [ #  # ]:          0 :     for( int i = 0; i < len; i++ )
     102                 :            :     {
     103                 :          0 :         int i1 = ( i + 1 ) % len;  // next vertex in polygon
     104                 :            :         // check intx with x axis
     105                 :          0 :         double ax = in_plane_positions[2 * i], ay = in_plane_positions[2 * i + 1];
     106                 :          0 :         double bx = in_plane_positions[2 * i1], by = in_plane_positions[2 * i1 + 1];
     107         [ #  # ]:          0 :         if( ay * by < 0 )  // it intersects with x axis
     108                 :            :         {
     109                 :          0 :             double alfa  = ay / ( ay - by );
     110                 :          0 :             double xintx = ax + alfa * ( bx - ax );
     111         [ #  # ]:          0 :             IntxUtils::reverse_gnomonic_projection( xintx, 0, R, plane, pos );
     112 [ #  # ][ #  # ]:          0 :             update_min( pos.array() );
     113 [ #  # ][ #  # ]:          0 :             update_max( pos.array() );
     114                 :            :         }
     115         [ #  # ]:          0 :         if( ax * bx < 0 )  // it intersects with y axis
     116                 :            :         {
     117                 :          0 :             double alfa  = ax / ( ax - bx );
     118                 :          0 :             double yintx = ay + alfa * ( by - ay );
     119         [ #  # ]:          0 :             IntxUtils::reverse_gnomonic_projection( 0, yintx, R, plane, pos );
     120 [ #  # ][ #  # ]:          0 :             update_min( pos.array() );
     121 [ #  # ][ #  # ]:          0 :             update_max( pos.array() );
     122                 :            :         }
     123                 :          0 :         oriented_area2 += ( ax * by - ay * bx );
     124                 :            :     }
     125         [ #  # ]:          0 :     if( fabs( oriented_area2 ) > R * R * 1.e-6 )  // origin is in the interior, add the center
     126                 :            :     {
     127         [ #  # ]:          0 :         IntxUtils::reverse_gnomonic_projection( 0, 0, R, plane, pos );
     128 [ #  # ][ #  # ]:          0 :         update_min( pos.array() );
     129 [ #  # ][ #  # ]:          0 :         update_max( pos.array() );
     130                 :            :     }
     131                 :          0 : }
     132 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11