76#include "DGtal/base/Common.h"
77#include "DGtal/shapes/SurfaceMesh.h"
79#include "DGtal/geometry/meshes/CorrectedNormalCurrentComputer.h"
81#include "DGtal/helpers/Shortcuts.h"
82#include "DGtal/helpers/ShortcutsGeometry.h"
83#include "DGtal/io/writers/SurfaceMeshWriter.h"
84#include "DGtal/io/colormaps/GradientColorMap.h"
85#include "DGtal/io/colormaps/QuantifiedColorMap.h"
99void usage(
int argc,
char* argv[] )
101 std::cout <<
"Usage: " << std::endl
102 <<
"\t" << argv[ 0 ] <<
" <filename.vol> <R> <m> <M> <Hmax> <Gmax>" << std::endl
104 <<
"Computation of mean and Gaussian curvatures on a vol file, " << std::endl
105 <<
"using interpolated corrected curvature measures (based " << std::endl
106 <<
"on the theory of corrected normal currents)." << std::endl
107 <<
"- builds the surface mesh from file <filename.vol>" << std::endl
108 <<
"- <R> is the radius of the measuring balls" << std::endl
109 <<
"- <m> is the min threshold value for the vol file" << std::endl
110 <<
"- <M> is the max threshold value for the vol file" << std::endl
111 <<
"- <Hmax> gives the colormap range [-Hmax,Hmax] for" << std::endl
112 <<
" the output of mean curvature estimates" << std::endl
113 <<
"- <Gmax> gives the colormap range [-Gmax,Gmax] for" << std::endl
114 <<
" the output of mean curvature estimates" << std::endl
115 <<
"It produces several OBJ files to display mean and" << std::endl
116 <<
"Gaussian curvature estimation results: `example-cnc-H.obj`" << std::endl
117 <<
"and `example-cnc-G.obj` as well as the associated MTL file." << std::endl;
120int main(
int argc,
char* argv[] )
128 using namespace DGtal;
136 std::string input = argv[ 1 ];
137 const double R = argc > 2 ? atof( argv[ 2 ] ) : 2.0;
138 const int m = argc > 3 ? atoi( argv[ 3 ] ) : 0;
139 const int M = argc > 4 ? atoi( argv[ 4 ] ) : 1;
140 const double Hmax = argc > 5 ? atof( argv[ 5 ] ) : 0.33;
141 const double Gmax = argc > 6 ? atof( argv[ 6 ] ) : 0.1;
145 auto params = SH::defaultParameters() | SHG::defaultParameters();
146 params(
"thresholdMin", m )(
"thresholdMax", M )(
"closed", 1);
147 params(
"t-ring", 3 )(
"surfaceTraversal",
"Default" );
148 auto bimage = SH::makeBinaryImage( input.c_str(), params );
149 if ( bimage ==
nullptr )
151 trace.
error() <<
"Unable to read file <" << input.c_str() <<
">" << std::endl;
154 auto K = SH::getKSpace( bimage, params );
155 auto sembedder = SH::getSCellEmbedder(
K );
156 auto embedder = SH::getCellEmbedder(
K );
157 auto surface = SH::makeDigitalSurface( bimage,
K, params );
158 auto surfels = SH::getSurfelRange( surface, params );
159 trace.
info() <<
"- surface has " << surfels.size()<<
" surfels." << std::endl;
164 std::vector< SM::Vertices > faces;
166 auto pointels = SH::getPointelRange( c2i, surface );
167 auto vertices = SH::RealPoints( pointels.size() );
168 std::transform( pointels.cbegin(), pointels.cend(), vertices.begin(),
169 [&] (
const SH::Cell& c) { return embedder( c ); } );
170 for (
auto&& surfel : *surface )
172 const auto primal_surfel_vtcs = SH::getPointelRange(
K, surfel );
174 for (
auto&& primal_vtx : primal_surfel_vtcs )
175 face.push_back( c2i[ primal_vtx ] );
176 faces.push_back( face );
178 smesh.init( vertices.cbegin(), vertices.cend(),
179 faces.cbegin(), faces.cend() );
180 trace.
info() << smesh << std::endl;
187 auto face_normals = SHG::getCTrivialNormalVectors( surface, surfels, params );
188 smesh.setFaceNormals( face_normals.cbegin(), face_normals.cend() );
192 std::cout <<
"Compute mu0" << std::endl;
193 auto mu0 = cnc.computeMu0();
194 std::cout <<
"Compute mu1" << std::endl;
195 auto mu1 = cnc.computeMu1();
196 std::cout <<
"Compute mu2" << std::endl;
197 auto mu2 = cnc.computeMu2();
202 std::vector< double > H( smesh.nbFaces() );
203 std::vector< double > G( smesh.nbFaces() );
204 for (
auto f = 0; f < smesh.nbFaces(); ++f )
206 const auto b = smesh.faceCentroid( f );
207 const auto area = mu0.measure( b, R, f );
208 H[ f ] = cnc.meanCurvature ( area, mu1.measure( b, R, f ) );
209 G[ f ] = cnc.GaussianCurvature( area, mu2.measure( b, R, f ) );
214 auto H_min_max = std::minmax_element( H.cbegin(), H.cend() );
215 auto G_min_max = std::minmax_element( G.cbegin(), G.cend() );
216 std::cout <<
"Computed mean curvatures:"
217 <<
" min=" << *H_min_max.first <<
" max=" << *H_min_max.second
219 std::cout <<
"Computed Gaussian curvatures:"
220 <<
" min=" << *G_min_max.first <<
" max=" << *G_min_max.second
226 smesh.vertexNormals() = SH::RealVectors();
227 smesh.faceNormals() = SH::RealVectors();
229 const auto colormapH = makeQuantifiedColorMap(
makeColorMap( -Hmax, Hmax ) );
230 const auto colormapG = makeQuantifiedColorMap(
makeColorMap( -Gmax, Gmax ) );
231 auto colorsH = SMW::Colors( smesh.nbFaces() );
232 auto colorsG = SMW::Colors( smesh.nbFaces() );
233 for (
auto i = 0; i < smesh.nbFaces(); i++ )
235 colorsH[ i ] = colormapH( H[ i ] );
236 colorsG[ i ] = colormapG( G[ i ] );
238 SMW::writeOBJ(
"example-cnc-H", smesh, colorsH );
239 SMW::writeOBJ(
"example-cnc-G", smesh, colorsG );
Structure representing an RGB triple with alpha component.
Aim: This class template may be used to (linearly) convert scalar values in a given range into a colo...
void addColor(const Color &color)
Aim: This class is used to simplify shape and surface creation. With it, you can create new shapes an...
Aim: This class is used to simplify shape and surface creation. With it, you can create new shapes an...
Z3i this namespace gathers the standard of types for 3D imagery.
DGtal is the top-level namespace which contains all DGtal functions and types.
Aim: Utility class to compute curvature measures induced by (1) a corrected normal current defined by...
Aim: An helper class for writing mesh file formats (Waverfront OBJ at this point) and creating a Surf...
Aim: Represents an embedded mesh as faces and a list of vertices. Vertices may be shared among faces ...
DGtal::GradientColorMap< double > makeColorMap(double min_value, double max_value)
[curvature-measures-Includes]