2 *  This program is free software: you can redistribute it and/or modify
 
    3 *  it under the terms of the GNU Lesser General Public License as
 
    4 *  published by the Free Software Foundation, either version 3 of the
 
    5 *  License, or  (at your option) any later version.
 
    7 *  This program is distributed in the hope that it will be useful,
 
    8 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
    9 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
   10 *  GNU General Public License for more details.
 
   12 *  You should have received a copy of the GNU General Public License
 
   13 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
   18 * @file NormalCycleComputer.ih
 
   19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
 
   20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
 
   24 * Implementation of inline methods defined in NormalCycleComputer.h
 
   26 * This file is part of the DGtal library.
 
   30//////////////////////////////////////////////////////////////////////////////
 
   32//////////////////////////////////////////////////////////////////////////////
 
   34///////////////////////////////////////////////////////////////////////////////
 
   35// IMPLEMENTATION of inline methods.
 
   36///////////////////////////////////////////////////////////////////////////////
 
   38///////////////////////////////////////////////////////////////////////////////
 
   39// ----------------------- Standard services ------------------------------
 
   41//-----------------------------------------------------------------------------
 
   42template <typename TRealPoint, typename TRealVector>
 
   43DGtal::NormalCycleComputer<TRealPoint, TRealVector>::
 
   44NormalCycleComputer( ConstAlias< SurfaceMesh > aMesh )
 
   49//-----------------------------------------------------------------------------
 
   50template <typename TRealPoint, typename TRealVector>
 
   51typename DGtal::NormalCycleComputer<TRealPoint, TRealVector>::ScalarMeasure
 
   52DGtal::NormalCycleComputer<TRealPoint, TRealVector>::
 
   55  ScalarMeasure mu0( &myMesh, 0.0 );
 
   56  auto& face_mu0 = mu0.kMeasures( 2 );
 
   57  face_mu0.resize( myMesh.nbFaces() );
 
   59  for ( const auto& f : myMesh.allIncidentVertices() )
 
   61      RealPoints  p( f.size() );
 
   62      for ( Index idx_v = 0; idx_v < f.size(); ++idx_v )
 
   63        p[ idx_v ] = myMesh.positions()    [ f[ idx_v ] ];
 
   64      face_mu0[ idx_f++ ] = Formula::area( p );
 
   69//-----------------------------------------------------------------------------
 
   70template <typename TRealPoint, typename TRealVector>
 
   71typename DGtal::NormalCycleComputer<TRealPoint, TRealVector>::ScalarMeasure
 
   72DGtal::NormalCycleComputer<TRealPoint, TRealVector>::
 
   75  ScalarMeasure mu1( &myMesh, 0.0 );
 
   76  auto& edge_mu1 = mu1.kMeasures( 1 );
 
   77  edge_mu1.resize( myMesh.nbEdges() );
 
   79  for ( const auto& e : myMesh.allEdgeVertices() )
 
   81      const auto & right_faces = myMesh.allEdgeRightFaces()[ idx_e ];
 
   82      const auto &  left_faces = myMesh.allEdgeLeftFaces ()[ idx_e ];
 
   83      if ( right_faces.size() != 1 || left_faces.size() != 1 )
 
   85          edge_mu1[ idx_e ] = 0.0;
 
   89          const RealPoint        a = myMesh.positions()[ e.first  ];
 
   90          const RealPoint        b = myMesh.positions()[ e.second ];
 
   91          const RealPoint    right = myMesh.faceCentroid( right_faces[ 0 ] );
 
   92          const RealPoint     left = myMesh.faceCentroid( left_faces [ 0 ] );
 
   93          const RealVector right_n = Formula::normal( a, right, b );
 
   94          const RealVector  left_n = Formula::normal( a, b, left  );
 
   95          edge_mu1[ idx_e ] = Formula::twiceMeanCurvature( a, b, right_n, left_n );
 
  102//-----------------------------------------------------------------------------
 
  103template <typename TRealPoint, typename TRealVector>
 
  104typename DGtal::NormalCycleComputer<TRealPoint, TRealVector>::ScalarMeasure
 
  105DGtal::NormalCycleComputer<TRealPoint, TRealVector>::
 
  108  ScalarMeasure mu2( &myMesh, 0.0 );
 
  109  auto& vertex_mu2 = mu2.kMeasures( 0 );
 
  110  vertex_mu2.resize( myMesh.nbVertices() );
 
  112  for ( const auto& faces_v : myMesh.allIncidentFaces() )
 
  114      const RealPoint a = myMesh.positions()[ idx_v ];
 
  116      for ( auto f : faces_v )
 
  118          const auto & vtcs = myMesh.allIncidentVertices()[ f ];
 
  119          Index j = std::find( vtcs.cbegin(), vtcs.cend(), idx_v ) - vtcs.cbegin();
 
  120          if ( j != vtcs.size() )
 
  122              const Index prev = ( j + vtcs.size() - 1 ) % vtcs.size();
 
  123              const Index next = ( j + vtcs.size() + 1 ) % vtcs.size();
 
  124              pairs.push_back( myMesh.positions()[ vtcs[ next ] ] );
 
  125              pairs.push_back( myMesh.positions()[ vtcs[ prev ] ] );
 
  128      vertex_mu2[ idx_v++ ] = Formula::gaussianCurvatureWithPairs( a, pairs );
 
  133//-----------------------------------------------------------------------------
 
  134template <typename TRealPoint, typename TRealVector>
 
  135typename DGtal::NormalCycleComputer<TRealPoint, TRealVector>::TensorMeasure
 
  136DGtal::NormalCycleComputer<TRealPoint, TRealVector>::
 
  139  const RealTensor zeroT { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
 
  140  TensorMeasure muXY( &myMesh, zeroT );
 
  141  auto& edge_muXY = muXY.kMeasures( 1 );
 
  142  edge_muXY.resize( myMesh.nbEdges() );
 
  144  for ( auto e : myMesh.allEdgeVertices() )
 
  146      const auto & right_faces = myMesh.allEdgeRightFaces()[ idx_e ];
 
  147      const auto &  left_faces = myMesh.allEdgeLeftFaces ()[ idx_e ];
 
  148      if ( right_faces.size() != 1 || left_faces.size() != 1 )
 
  149        edge_muXY[ idx_e ] = zeroT;
 
  152          const RealPoint        a = myMesh.positions()[ e.first  ];
 
  153          const RealPoint        b = myMesh.positions()[ e.second ];
 
  154          const RealPoint    right = myMesh.faceCentroid( right_faces[ 0 ] );
 
  155          const RealPoint     left = myMesh.faceCentroid( left_faces [ 0 ] );
 
  156          const RealVector right_n = Formula::normal( a, right, b );
 
  157          const RealVector  left_n = Formula::normal( a, b, left  );
 
  159            Formula::anisotropicCurvatureH1( a, b, right_n, left_n );
 
  166//-----------------------------------------------------------------------------
 
  167template <typename TRealPoint, typename TRealVector>
 
  168typename DGtal::NormalCycleComputer<TRealPoint, TRealVector>::TensorMeasure
 
  169DGtal::NormalCycleComputer<TRealPoint, TRealVector>::
 
  172  const RealTensor zeroT { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
 
  173  TensorMeasure muXYs( &myMesh, zeroT );
 
  174  auto& edge_muXYs = muXYs.kMeasures( 1 );
 
  175  edge_muXYs.resize( myMesh.nbEdges() );
 
  177  for ( auto e : myMesh.allEdgeVertices() )
 
  179      const auto & right_faces = myMesh.allEdgeRightFaces()[ idx_e ];
 
  180      const auto &  left_faces = myMesh.allEdgeLeftFaces ()[ idx_e ];
 
  181      if ( right_faces.size() != 1 || left_faces.size() != 1 )
 
  182        edge_muXYs[ idx_e ] = zeroT;
 
  185          const RealPoint        a = myMesh.positions()[ e.first  ];
 
  186          const RealPoint        b = myMesh.positions()[ e.second ];
 
  187          const RealPoint    right = myMesh.faceCentroid( right_faces[ 0 ] );
 
  188          const RealPoint     left = myMesh.faceCentroid( left_faces [ 0 ] );
 
  189          const RealVector right_n = Formula::normal( a, right, b );
 
  190          const RealVector  left_n = Formula::normal( a, b, left  );
 
  191          edge_muXYs[ idx_e ] =
 
  192            Formula::anisotropicCurvatureH2( a, b, right_n, left_n );
 
  200///////////////////////////////////////////////////////////////////////////////
 
  201///////////////////////////////////////////////////////////////////////////////