LCOV - code coverage report
Current view: top level - src/moab - OrientedBox.hpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 20 23 87.0 %
Date: 2020-12-16 07:07:30 Functions: 13 15 86.7 %
Branches: 2 4 50.0 %

           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                 :            : /**\file OrientedBox.hpp
      17                 :            :  *\author Jason Kraftcheck ([email protected])
      18                 :            :  *\date 2006-07-18
      19                 :            :  */
      20                 :            : 
      21                 :            : #ifndef MB_ORIENTED_BOX_HPP
      22                 :            : #define MB_ORIENTED_BOX_HPP
      23                 :            : 
      24                 :            : #include "moab/Forward.hpp"
      25                 :            : #include "moab/CartVect.hpp"
      26                 :            : #include "moab/Matrix3.hpp"
      27                 :            : 
      28                 :            : #include <iosfwd>
      29                 :            : 
      30                 :            : namespace moab
      31                 :            : {
      32                 :            : 
      33                 :            : #define MB_ORIENTED_BOX_UNIT_VECTORS 1
      34                 :            : #define MB_ORIENTED_BOX_OUTER_RADIUS 1
      35                 :            : 
      36                 :            : class Range;
      37                 :            : 
      38                 :            : /**\brief Oriented bounding box
      39                 :            :  */
      40                 :          0 : class OrientedBox
      41                 :            : {
      42                 :            :   private:
      43                 :            :     void order_axes_by_length( double ax1_len, double ax2_len,
      44                 :            :                                double ax3_len );  //!< orders the box axes by the given lengths for each axis
      45                 :            : 
      46                 :            :   public:
      47                 :            :     CartVect center;  //!< Box center
      48                 :            :     Matrix3 axes;     //!< Box axes, unit vectors sorted by extent of box along axis
      49                 :            : #if MB_ORIENTED_BOX_UNIT_VECTORS
      50                 :            :     CartVect length;  //!< distance from center to plane along each axis
      51                 :            : #endif
      52                 :            : #if MB_ORIENTED_BOX_OUTER_RADIUS
      53                 :            :     double radius;  //!< outer radius (1/2 diagonal length) of box
      54                 :            : #endif
      55                 :            : 
      56                 :     332684 :     inline OrientedBox() : radius( 0.0 ) {}
      57                 :            : 
      58                 :            :     OrientedBox( const Matrix3& axes_mat, const CartVect& center );
      59                 :            :     OrientedBox( const CartVect axes_in[3], const CartVect& center );
      60                 :            : 
      61                 :            :     inline double inner_radius() const;  //!< radius of inscribed sphere
      62                 :            :     inline double outer_radius() const;  //!< radius of circumscribed sphere
      63                 :            :     inline double outer_radius_squared(
      64                 :            :         const double reps ) const;  //!< square of (radius+at least epsilon) of circumsphere
      65                 :            :     inline double inner_radius_squared( const double reps ) const;  //!< square of (radius-epsilon) of inscribed sphere
      66                 :            :     inline double volume() const;                                   //!< volume of box
      67                 :            :     inline CartVect dimensions() const;                             //!< number of dimensions for which box is not flat
      68                 :            :     inline double area() const;                                     //!< largest side area
      69                 :            :     inline CartVect axis( int index ) const;                        //!< get unit vector in direction of axis
      70                 :            :     inline CartVect scaled_axis( int index ) const;  //!< get vector in direction of axis, scaled to its true length
      71                 :            : 
      72                 :            :     /** Test if point is contained in box */
      73                 :            :     bool contained( const CartVect& point, double tolerance ) const;
      74                 :            : 
      75                 :            :     // bool contained( const OrientedBox& other, double tolerance ) const;
      76                 :            : 
      77                 :            :     /**\brief get tag handle for storing oriented box
      78                 :            :      *
      79                 :            :      * Get the handle for the tag with the specified name and
      80                 :            :      * check that the tag is appropriate for storing instances
      81                 :            :      * of OrientedBox.  The resulting tag may be used to store
      82                 :            :      * instances of OrientedBox directly.
      83                 :            :      *
      84                 :            :      *\param handle_out  The TagHandle, passed back to caller
      85                 :            :      *\param name        The tag name
      86                 :            :      *\param create      If true, tag will be created if it does not exist
      87                 :            :      */
      88                 :            :     static ErrorCode tag_handle( Tag& handle_out, Interface* instance, const char* name );
      89                 :            : 
      90                 :            :     /**\brief Calculate an oriented box from a set of vertices */
      91                 :            :     static ErrorCode compute_from_vertices( OrientedBox& result, Interface* instance, const Range& vertices );
      92                 :            : 
      93                 :            :     /**\brief Calculate an oriented box from a set of 2D elements */
      94                 :            :     static ErrorCode compute_from_2d_cells( OrientedBox& result, Interface* instance, const Range& elements );
      95                 :            : 
      96                 :            :     /** Structure to hold temporary accumulated triangle data for
      97                 :            :      *  calculating box orientation.  See box_from_covariance_data
      98                 :            :      *  to see how this is used to calculate the final covariance matrix
      99                 :            :      *  and resulting box orientation.
     100                 :            :      */
     101                 :      10046 :     struct CovarienceData
     102                 :            :     {
     103                 :      48324 :         CovarienceData() : area( 0.0 ) {}
     104                 :       1598 :         CovarienceData( const Matrix3& m, const CartVect& c, double a ) : matrix( m ), center( c ), area( a ) {}
     105                 :            :         Matrix3 matrix;   //!< Running sum for covariance matrix
     106                 :            :         CartVect center;  //!< Sum of triangle centroids weighted by 2*triangle area
     107                 :            :         double area;      //!< 2x the sum of the triangle areas
     108                 :            :     };
     109                 :            : 
     110                 :            :     /** Calculate a CovarienceData struct from a list of triangles */
     111                 :            :     static ErrorCode covariance_data_from_tris( CovarienceData& result, Interface* moab_instance,
     112                 :            :                                                 const Range& elements );
     113                 :            : 
     114                 :            :     /** Calculate an OrientedBox given an array of CovarienceData and
     115                 :            :      *  the list  of vertices the box is to bound.
     116                 :            :      */
     117                 :            :     static ErrorCode compute_from_covariance_data( OrientedBox& result, Interface* moab_instance,
     118                 :            :                                                    const CovarienceData* orient_array, unsigned orient_array_length,
     119                 :            :                                                    const Range& vertices );
     120                 :            : 
     121                 :            :     /** Test for intersection of a ray (or line segment) with this box.
     122                 :            :      *  Ray length limits are used to optimize Monte Carlo particle tracking.
     123                 :            :      *\param ray_start_point     The base point of the ray
     124                 :            :      *\param ray_unit_direction  The direction of the ray (must be unit length)
     125                 :            :      *\param distance_tolerance  Tolerance to use in intersection checks
     126                 :            :      *\param nonnegative_ray_len Optional length of ray in forward direction
     127                 :            :      *\param negative_ray_len    Optional length of ray in reverse direction
     128                 :            :      */
     129                 :            :     bool intersect_ray( const CartVect& ray_start_point, const CartVect& ray_unit_direction,
     130                 :            :                         const double distance_tolerance, const double* nonnegatve_ray_len = 0,
     131                 :            :                         const double* negative_ray_len = 0 ) const;
     132                 :            : 
     133                 :            :     /**\brief Find closest position on/within box to input position.
     134                 :            :      *
     135                 :            :      * Find the closest position in the solid box to the input position.
     136                 :            :      * If the input position is on or within the box, then the output
     137                 :            :      * position will be the same as the input position.  If the input
     138                 :            :      * position is outside the box, the outside position will be the
     139                 :            :      * closest point on the box boundary to the input position.
     140                 :            :      */
     141                 :            :     void closest_location_in_box( const CartVect& input_position, CartVect& output_position ) const;
     142                 :            : 
     143                 :            :     //! Construct a hexahedral element with the same shape as this box.
     144                 :            :     ErrorCode make_hex( EntityHandle& hex, Interface* instance );
     145                 :            : 
     146                 :            :     /** Calculate an OrientedBox given a CovarienceData struct and
     147                 :            :      *  the list of points the box is to bound.
     148                 :            :      */
     149                 :            :     static ErrorCode compute_from_covariance_data( OrientedBox& result, Interface* moab_instance,
     150                 :            :                                                    CovarienceData& orientation_data, const Range& vertices );
     151                 :            : };
     152                 :            : 
     153                 :            : std::ostream& operator<<( std::ostream&, const OrientedBox& );
     154                 :            : 
     155                 :          5 : double OrientedBox::inner_radius() const
     156                 :            : {
     157                 :            : #if MB_ORIENTED_BOX_UNIT_VECTORS
     158                 :          5 :     return length[0];
     159                 :            : #else
     160                 :            :     return axes.col( 0 ).length();
     161                 :            : #endif
     162                 :            : }
     163                 :            : 
     164                 :          5 : double OrientedBox::outer_radius() const
     165                 :            : {
     166                 :            : #if MB_ORIENTED_BOX_OUTER_RADIUS
     167                 :          5 :     return radius;
     168                 :            : #elif MB_ORIENTED_BOX_UNIT_VECTORS
     169                 :            :     return length.length();
     170                 :            : #else
     171                 :            :     return ( axes.col( 0 ) + axes.col( 1 ) + axes.col( 2 ) ).length();
     172                 :            : #endif
     173                 :            : }
     174                 :            : 
     175                 :            : // Add at least epsilon to the radius, before squaring it.
     176                 :      31642 : double OrientedBox::outer_radius_squared( const double reps ) const
     177                 :            : {
     178                 :            : #if MB_ORIENTED_BOX_OUTER_RADIUS
     179                 :      31642 :     return ( radius + reps ) * ( radius + reps );
     180                 :            : #elif MB_ORIENTED_BOX_UNIT_VECTORS
     181                 :            :     CartVect tmp( length[0] + reps, length[1] + reps, length[2] + reps );
     182                 :            :     return tmp % tmp;
     183                 :            : #else
     184                 :            :     CartVect half_diag = axes.col( 0 ) + axes.col( 1 ) + axes.col( 2 );
     185                 :            :     half_diag += CartVect( reps, reps, reps );
     186                 :            :     return half_diag % half_diag;
     187                 :            : #endif
     188                 :            : }
     189                 :            : 
     190                 :            : // Subtract epsilon from the length of the shortest axis, before squaring it.
     191                 :      25621 : double OrientedBox::inner_radius_squared( const double reps ) const
     192                 :            : {
     193                 :            : #if MB_ORIENTED_BOX_UNIT_VECTORS
     194                 :      25621 :     return ( length[0] - reps ) * ( length[0] - reps );
     195                 :            : #else
     196                 :            :     CartVect tmp = axes.col( 0 );
     197                 :            :     tmp -= CartVect( reps, reps, reps );
     198                 :            :     return ( tmp % tmp );
     199                 :            : #endif
     200                 :            : }
     201                 :            : 
     202                 :          5 : double OrientedBox::volume() const
     203                 :            : {
     204                 :            : #if MB_ORIENTED_BOX_UNIT_VECTORS
     205                 :          5 :     return 8 * length[0] * length[1] * length[2];
     206                 :            : #else
     207                 :            :     return fabs( 8 * axes.col( 0 ) % ( axes.col( 1 ) * axes.col( 2 ) ) );
     208                 :            : #endif
     209                 :            : }
     210                 :            : 
     211                 :          6 : CartVect OrientedBox::dimensions() const
     212                 :            : {
     213                 :            : #if MB_ORIENTED_BOX_UNIT_VECTORS
     214                 :          6 :     return 2.0 * length;
     215                 :            : #else
     216                 :            :     return 2.0 * CartVect( axes.col( 0 ).length(), axes.col( 1 ).length(), axes.col( 2 ).length() );
     217                 :            : #endif
     218                 :            : }
     219                 :            : 
     220                 :          0 : double OrientedBox::area() const
     221                 :            : {
     222                 :            : #if MB_ORIENTED_BOX_UNIT_VECTORS
     223                 :          0 :     return 4 * length[1] * length[2];
     224                 :            : #else
     225                 :            :     return 4 * ( axes.col( 1 ) * axes.col( 2 ) ).length();
     226                 :            : #endif
     227                 :            : }
     228                 :            : 
     229                 :     858866 : CartVect OrientedBox::axis( int index ) const
     230                 :            : {
     231                 :     858866 :     return axes.col( index );
     232                 :            : }
     233                 :            : 
     234                 :      12616 : CartVect OrientedBox::scaled_axis( int index ) const
     235                 :            : {
     236                 :            : #if MB_ORIENTED_BOX_UNIT_VECTORS
     237 [ +  - ][ +  - ]:      12616 :     return length[index] * axes.col( index );
     238                 :            : #else
     239                 :            :     return axes.col( index );
     240                 :            : #endif
     241                 :            : }
     242                 :            : 
     243                 :            : }  // namespace moab
     244                 :            : 
     245                 :            : #endif

Generated by: LCOV version 1.11