LCOV - code coverage report
Current view: top level - src/mesquite/Misc - PlanarDomain.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 62 70 88.6 %
Date: 2020-07-18 00:09:26 Functions: 12 13 92.3 %
Branches: 89 216 41.2 %

           Branch data     Line data    Source code
       1                 :            : /* *****************************************************************
       2                 :            :     MESQUITE -- The Mesh Quality Improvement Toolkit
       3                 :            : 
       4                 :            :     Copyright 2004 Sandia Corporation and Argonne National
       5                 :            :     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
       6                 :            :     with Sandia Corporation, the U.S. Government retains certain
       7                 :            :     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                 :            :     This library is distributed in the hope that it will be useful,
      15                 :            :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :            :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17                 :            :     Lesser General Public License for more details.
      18                 :            : 
      19                 :            :     You should have received a copy of the GNU Lesser General Public License
      20                 :            :     (lgpl.txt) along with this library; if not, write to the Free Software
      21                 :            :     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      22                 :            : 
      23                 :            :     [email protected], [email protected], [email protected],
      24                 :            :     [email protected], [email protected], [email protected],
      25                 :            :     [email protected]
      26                 :            : 
      27                 :            :   ***************************************************************** */
      28                 :            : #include "PlanarDomain.hpp"
      29                 :            : #include "MsqError.hpp"
      30                 :            : #include "MsqVertex.hpp"
      31                 :            : #include "DomainUtil.hpp"
      32                 :            : 
      33                 :            : #include <algorithm>
      34                 :            : 
      35         [ -  + ]:        104 : MBMesquite::PlanarDomain::~PlanarDomain() {}
      36                 :            : 
      37                 :         51 : void MBMesquite::PlanarDomain::set_plane( const MBMesquite::Vector3D& normal, const MBMesquite::Vector3D& point )
      38                 :            : {
      39                 :         51 :     mNormal = normal;
      40                 :         51 :     mNormal.normalize();
      41                 :         51 :     mCoeff = -( mNormal % point );
      42                 :         51 : }
      43                 :            : 
      44                 :    1421335 : void MBMesquite::PlanarDomain::snap_to( MBMesquite::Mesh::VertexHandle /*entity_handle*/, Vector3D& coordinate ) const
      45                 :            : {
      46         [ +  - ]:    1421335 :     coordinate -= mNormal * ( mNormal % coordinate + mCoeff );
      47                 :    1421335 : }
      48                 :            : 
      49                 :          0 : void MBMesquite::PlanarDomain::vertex_normal_at( MBMesquite::Mesh::VertexHandle /*entity_handle*/,
      50                 :            :                                                  MBMesquite::Vector3D& coordinate ) const
      51                 :            : {
      52                 :          0 :     coordinate = mNormal;
      53                 :          0 : }
      54                 :            : 
      55                 :     267950 : void MBMesquite::PlanarDomain::element_normal_at( MBMesquite::Mesh::ElementHandle /*entity_handle*/,
      56                 :            :                                                   MBMesquite::Vector3D& coordinate ) const
      57                 :            : {
      58                 :     267950 :     coordinate = mNormal;
      59                 :     267950 : }
      60                 :            : 
      61                 :      96692 : void MBMesquite::PlanarDomain::vertex_normal_at( const MBMesquite::Mesh::VertexHandle*, Vector3D coords[],
      62                 :            :                                                  unsigned count, MBMesquite::MsqError& ) const
      63                 :            : {
      64         [ +  + ]:     784991 :     for( unsigned i = 0; i < count; ++i )
      65                 :     688299 :         coords[i] = mNormal;
      66                 :      96692 : }
      67                 :            : 
      68                 :     229509 : void MBMesquite::PlanarDomain::closest_point( MBMesquite::Mesh::VertexHandle, const MBMesquite::Vector3D& position,
      69                 :            :                                               MBMesquite::Vector3D& closest, MBMesquite::Vector3D& normal,
      70                 :            :                                               MBMesquite::MsqError& ) const
      71                 :            : {
      72                 :     229509 :     normal  = mNormal;
      73 [ +  - ][ +  - ]:     229509 :     closest = position - mNormal * ( mNormal % position + mCoeff );
      74                 :     229509 : }
      75                 :            : 
      76                 :      96692 : void MBMesquite::PlanarDomain::domain_DoF( const Mesh::VertexHandle*, unsigned short* dof_array, size_t num_vertices,
      77                 :            :                                            MsqError& ) const
      78                 :            : {
      79         [ +  - ]:      96692 :     std::fill( dof_array, dof_array + num_vertices, 2 );
      80                 :      96692 : }
      81                 :            : 
      82                 :          4 : void MBMesquite::PlanarDomain::flip()
      83                 :            : {
      84         [ +  - ]:          4 :     mNormal = -mNormal;
      85                 :          4 :     mCoeff  = -mCoeff;
      86                 :          4 : }
      87                 :            : 
      88                 :          4 : void MBMesquite::PlanarDomain::fit_vertices( Mesh* mesh, MsqError& err, double epsilon )
      89                 :            : {
      90                 :            :     // Our goal here is to consider only the boundary (fixed) vertices
      91                 :            :     // when calculating the plane.  If for some reason the user wants
      92                 :            :     // to snap a not-quite-planar mesh to a plane during optimization,
      93                 :            :     // if possible we want to start with the plane containing the fixed
      94                 :            :     // vertices, as those won't get snapped.  If no vertices are fixed,
      95                 :            :     // then treat them all as fixed for the purpose calculating the plane
      96                 :            :     // (consider them all.)
      97                 :            : 
      98 [ +  - ][ +  - ]:          8 :     std::vector< Mesh::VertexHandle > verts, fixed;
                 [ +  - ]
      99 [ +  - ][ +  - ]:          4 :     mesh->get_all_vertices( verts, err );MSQ_ERRRTN( err );
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
     100 [ +  - ][ +  - ]:          4 :     DomainUtil::get_fixed_vertices( mesh, arrptr( verts ), verts.size(), fixed, err );MSQ_ERRRTN( err );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
                 [ -  + ]
     101                 :            : 
     102                 :          4 :     bool do_all_verts = true;
     103         [ +  - ]:          4 :     if( fixed.size() > 2 )
     104                 :            :     {
     105                 :          4 :         do_all_verts = false;
     106 [ +  - ][ +  - ]:          4 :         fit_vertices( mesh, arrptr( fixed ), fixed.size(), err, epsilon );
     107                 :            : 
     108                 :            :         // if we failed with only the fixed vertices, try again with all of the
     109                 :            :         // vertices
     110 [ +  - ][ -  + ]:          4 :         if( err )
     111                 :            :         {
     112         [ #  # ]:          0 :             err.clear();
     113                 :          0 :             do_all_verts = true;
     114                 :            :         }
     115                 :            :     }
     116                 :            : 
     117         [ -  + ]:          4 :     if( do_all_verts )
     118                 :            :     {
     119 [ #  # ][ #  # ]:          0 :         fit_vertices( mesh, arrptr( verts ), verts.size(), err, epsilon );MSQ_ERRRTN( err );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     120                 :            :     }
     121                 :            : 
     122                 :            :     // now count inverted elements
     123                 :          4 :     size_t inverted_count = 0, total_count = 0;
     124 [ +  - ][ +  - ]:          8 :     std::vector< Mesh::ElementHandle > elems;
     125 [ +  - ][ +  - ]:          8 :     std::vector< size_t > junk;
     126 [ +  - ][ +  - ]:          8 :     std::vector< MsqVertex > coords;
     127 [ +  - ][ +  - ]:          4 :     mesh->get_all_elements( elems, err );MSQ_ERRRTN( err );
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
     128         [ +  + ]:        204 :     for( size_t i = 0; i < elems.size(); ++i )
     129                 :            :     {
     130                 :            : 
     131                 :            :         EntityTopology type;
     132 [ +  - ][ +  - ]:        200 :         mesh->elements_get_topologies( &elems[i], &type, 1, err );
     133 [ +  - ][ -  + ]:        200 :         if( TopologyInfo::dimension( type ) != 2 ) continue;
     134                 :            : 
     135                 :        200 :         verts.clear();
     136 [ +  - ][ +  - ]:        200 :         mesh->elements_get_attached_vertices( arrptr( elems ), 1, verts, junk, err );MSQ_ERRRTN( err );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
                 [ -  + ]
     137         [ -  + ]:        200 :         if( verts.size() < 3 ) continue;
     138                 :            : 
     139         [ +  - ]:        200 :         coords.resize( verts.size() );
     140 [ +  - ][ +  - ]:        200 :         mesh->vertices_get_coordinates( arrptr( verts ), arrptr( coords ), 3, err );MSQ_ERRRTN( err );
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ -  + ]
     141 [ +  - ][ +  - ]:        200 :         Vector3D n = ( coords[1] - coords[0] ) * ( coords[2] - coords[0] );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     142                 :        200 :         ++total_count;
     143 [ +  - ][ +  - ]:        200 :         if( n % mNormal < 0.0 ) ++inverted_count;
     144                 :            :     }
     145                 :            : 
     146                 :            :     // if most elements are inverted, flip normal
     147 [ +  - ][ +  - ]:          8 :     if( 2 * inverted_count > total_count ) this->flip();
                 [ +  - ]
     148                 :            : }
     149                 :            : 
     150                 :          4 : void MBMesquite::PlanarDomain::fit_vertices( MBMesquite::Mesh* mesh, const MBMesquite::Mesh::VertexHandle* verts,
     151                 :            :                                              size_t num_verts, MBMesquite::MsqError& err, double epsilon )
     152                 :            : {
     153         [ +  - ]:          4 :     std::vector< MsqVertex > coords( num_verts );
     154 [ +  - ][ +  - ]:          4 :     mesh->vertices_get_coordinates( verts, arrptr( coords ), num_verts, err );MSQ_ERRRTN( err );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
                 [ -  + ]
     155                 :            : 
     156 [ +  - ][ +  - ]:          4 :     if( epsilon <= 0.0 ) epsilon = DomainUtil::default_tolerance( arrptr( coords ), num_verts );
                 [ +  - ]
     157                 :            : 
     158 [ +  - ][ +  + ]:         16 :     Vector3D pts[3];
     159 [ +  - ][ +  - ]:          4 :     if( !DomainUtil::non_colinear_vertices( arrptr( coords ), num_verts, pts, epsilon ) )
                 [ -  + ]
     160                 :            :     {
     161 [ #  # ][ #  # ]:          0 :         MSQ_SETERR( err )( "All vertices are colinear", MsqError::INVALID_MESH );
     162                 :          0 :         return;
     163                 :            :     }
     164                 :            : 
     165 [ +  - ][ +  - ]:          4 :     this->set_plane( ( pts[1] - pts[0] ) * ( pts[2] - pts[0] ), pts[0] );
         [ +  - ][ +  - ]
                 [ +  - ]
     166 [ +  - ][ +  - ]:         64 : }

Generated by: LCOV version 1.11