50 unsigned int nb = 0, nbok = 0;
55 trace.
beginBlock (
"Load vol file -> build digital surface -> estimate mean curvature -> save OBJ." );
58 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
59 params(
"colormap",
"Tics" );
62 auto bimage = SH3::makeBinaryImage( examplesPath +
"samples/Al.100.vol", params );
63 auto K = SH3::getKSpace( bimage, params );
64 auto surface = SH3::makeDigitalSurface( bimage,
K, params );
65 auto surfels = SH3::getSurfelRange(
surface, params );
66 auto curv = SHG3::getIIMeanCurvatures( bimage, surfels, params );
69 auto cmap = SH3::getColorMap( -0.5, 0.5, params );
70 auto colors = SH3::Colors( surfels.size() );
71 std::transform( curv.cbegin(), curv.cend(), colors.begin(), cmap );
72 bool ok = SH3::saveOBJ(
surface, SH3::RealVectors(), colors,
75 ++nb; nbok += ok ? 1 : 0;
79 trace.
beginBlock (
"Load vol file -> build digital surface -> estimate Gauss curvature -> save OBJ." );
81 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
82 params(
"colormap",
"Tics" );
83 auto bimage = SH3::makeBinaryImage( examplesPath +
"samples/Al.100.vol", params );
84 auto K = SH3::getKSpace( bimage, params );
85 auto surface = SH3::makeDigitalSurface( bimage,
K, params );
86 auto surfels = SH3::getSurfelRange(
surface, params );
87 auto curv = SHG3::getIIGaussianCurvatures( bimage, surfels, params );
88 auto cmap = SH3::getColorMap( -0.25, 0.25, params );
89 auto colors = SH3::Colors( surfels.size() );
90 std::transform( curv.cbegin(), curv.cend(), colors.begin(), cmap );
91 bool ok = SH3::saveOBJ(
surface, SH3::RealVectors(), colors,
93 ++nb; nbok += ok ? 1 : 0;
97 trace.
beginBlock (
"Build polynomial shape -> digitize -> extract ground-truth geometry." );
99 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
101 params(
"polynomial",
"3*x^2+2*y^2+z^2-90" )(
"gridstep", 0.25 );
102 auto implicit_shape = SH3::makeImplicitShape3D ( params );
103 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
104 auto binary_image = SH3::makeBinaryImage ( digitized_shape, params );
105 auto K = SH3::getKSpace( params );
107 auto surfels = SH3::getSurfelRange(
surface, params );
108 auto positions = SHG3::getPositions( implicit_shape,
K, surfels, params );
109 auto normals = SHG3::getNormalVectors( implicit_shape,
K, surfels, params );
110 auto mean_curvs = SHG3::getMeanCurvatures( implicit_shape,
K, surfels, params );
111 auto gauss_curvs = SHG3::getGaussianCurvatures( implicit_shape,
K, surfels, params );
113 auto stat_mean = SHG3::getStatistic( mean_curvs );
114 auto stat_gauss = SHG3::getStatistic( gauss_curvs );
115 trace.
info() <<
" min(H)=" << stat_mean.min()
116 <<
" avg(H)=" << stat_mean.mean()
117 <<
" max(H)=" << stat_mean.max() << std::endl;
118 trace.
info() <<
" min(G)=" << stat_gauss.min()
119 <<
" avg(G)=" << stat_gauss.mean()
120 <<
" max(G)=" << stat_gauss.max() << std::endl;
121 ++nb; nbok += positions.size() == surfels.size() ? 1 : 0;
122 ++nb; nbok += normals.size() == surfels.size() ? 1 : 0;
123 ++nb; nbok += mean_curvs.size() == surfels.size() ? 1 : 0;
124 ++nb; nbok += gauss_curvs.size() == surfels.size() ? 1 : 0;
125 ++nb; nbok += stat_mean.min() > 0.08 ? 1 : 0;
126 ++nb; nbok += stat_gauss.min() > 0.0064 ? 1 : 0;
130 trace.
beginBlock (
"Build polynomial shape -> digitize -> get pointels -> save projected quadrangulated surface." );
132 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
134 const double h = 0.25;
135 params(
"polynomial",
"goursat" )(
"gridstep", h );
136 auto implicit_shape = SH3::makeImplicitShape3D ( params );
137 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
138 auto binary_image = SH3::makeBinaryImage ( digitized_shape, params );
139 auto K = SH3::getKSpace( params );
140 auto embedder = SH3::getCellEmbedder(
K );
143 auto pointels = SH3::getPointelRange( c2i,
surface );
144 SH3::RealPoints pos( pointels.size() );
145 std::transform( pointels.cbegin(), pointels.cend(), pos.begin(),
146 [&] (
const SH3::Cell& c) { return h * embedder( c ); } );
147 auto ppos = SHG3::getPositions( implicit_shape, pos, params );
148 bool ok = SH3::saveOBJ(
surface,
149 [&] (
const SH3::Cell& c){
return ppos[ c2i[ c ] ];},
150 SH3::RealVectors(), SH3::Colors(),
151 "goursat-quad-proj.obj" );
153 ++nb; nbok += ok ? 1 : 0;
157 trace.
beginBlock (
"Build polynomial shape -> digitize -> extract mean curvature -> save as OBJ with colors." );
159 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
161 params(
"polynomial",
"goursat" )(
"gridstep", 0.25 )(
"colormap",
"Tics" );
162 auto implicit_shape = SH3::makeImplicitShape3D ( params );
163 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
164 auto binary_image = SH3::makeBinaryImage ( digitized_shape, params );
165 auto K = SH3::getKSpace( params );
167 auto surfels = SH3::getSurfelRange(
surface, params );
168 auto mean_curv = SHG3::getMeanCurvatures( implicit_shape,
K, surfels, params );
169 auto cmap = SH3::getColorMap( -0.3, 0.3, params );
170 auto colors = SH3::Colors( surfels.size() );
171 std::transform( mean_curv.cbegin(), mean_curv.cend(), colors.begin(), cmap );
172 bool ok = SH3::saveOBJ(
surface, SH3::RealVectors(), colors,
175 ++nb; nbok += ok ? 1 : 0;
179 trace.
beginBlock (
"Build polynomial shape -> digitize -> extract ground-truth and estimated mean curvature -> display errors in OBJ with colors." );
181 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
183 params(
"polynomial",
"goursat" )(
"gridstep", 0.25 )(
"colormap",
"Tics" )
185 auto implicit_shape = SH3::makeImplicitShape3D ( params );
186 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
187 auto bimage = SH3::makeBinaryImage ( digitized_shape, params );
188 auto K = SH3::getKSpace( params );
189 auto surface = SH3::makeLightDigitalSurface( bimage,
K, params );
190 auto surfels = SH3::getSurfelRange(
surface, params );
191 auto t_curv = SHG3::getMeanCurvatures( implicit_shape,
K, surfels, params );
192 auto ii_curv = SHG3::getIIMeanCurvatures( bimage, surfels, params );
193 auto cmap = SH3::getColorMap( -0.5, 0.5, params );
194 auto colors = SH3::Colors( surfels.size() );
195 std::transform( t_curv.cbegin(), t_curv.cend(), colors.begin(), cmap );
196 bool ok_t = SH3::saveOBJ(
surface, SH3::RealVectors(), colors,
"goursat-H.obj" );
197 std::transform( ii_curv.cbegin(), ii_curv.cend(), colors.begin(), cmap );
198 bool ok_ii = SH3::saveOBJ(
surface, SH3::RealVectors(), colors,
"goursat-H-ii.obj" );
199 auto errors = SHG3::getScalarsAbsoluteDifference( t_curv, ii_curv );
200 auto stat_errors = SHG3::getStatistic( errors );
201 auto cmap_errors = SH3::getColorMap( 0.0, stat_errors.max(), params );
202 std::transform( errors.cbegin(), errors.cend(), colors.begin(), cmap_errors );
203 bool ok_err = SH3::saveOBJ(
surface, SH3::RealVectors(), colors,
"goursat-H-ii-err.obj" );
204 trace.
info() <<
"Error Loo=" << SHG3::getScalarsNormLoo( t_curv, ii_curv )
205 <<
" L1=" << SHG3::getScalarsNormL1 ( t_curv, ii_curv )
206 <<
" L2=" << SHG3::getScalarsNormL2 ( t_curv, ii_curv )
209 ++nb; nbok += ( ok_t && ok_ii && ok_err ) ? 1 : 0;
213 trace.
beginBlock (
"Build polynomial shape -> digitize -> build digital surface -> save primal surface with VCM normals as obj." );
215 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
217 params(
"polynomial",
"goursat" )(
"gridstep", 0.25 )
218 (
"surfaceTraversal",
"Default" );
219 auto implicit_shape = SH3::makeImplicitShape3D ( params );
220 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
221 auto K = SH3::getKSpace( params );
222 auto binary_image = SH3::makeBinaryImage( digitized_shape, params );
224 auto surfels = SH3::getSurfelRange(
surface, params );
225 auto vcm_normals = SHG3::getVCMNormalVectors(
surface, surfels, params );
226 bool ok = SH3::saveOBJ(
surface, vcm_normals, SH3::Colors(),
227 "goursat-primal-vcm.obj" );
229 ++nb; nbok += ok ? 1 : 0;
233 trace.
beginBlock (
"Build polynomial shape -> digitize implicitly -> estimate II normals and curvature." );
235 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
237 params(
"polynomial",
"goursat" )(
"gridstep", .25 );
238 auto implicit_shape = SH3::makeImplicitShape3D ( params );
239 auto dig_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
240 auto K = SH3::getKSpace ( params );
241 auto surface = SH3::makeDigitalSurface ( dig_shape,
K, params );
242 auto surfels = SH3::getSurfelRange (
surface, params(
"surfaceTraversal",
"DepthFirst" ) );
243 auto def_surfels = SH3::getSurfelRange (
surface, params(
"surfaceTraversal",
"Default" ) );
244 auto ii_normals = SHG3::getIINormalVectors ( dig_shape, surfels, params );
246 auto ii_mean_curv = SHG3::getIIMeanCurvatures ( dig_shape, def_surfels, params );
249 auto ii_mean_curv2 = SHG3::getIIMeanCurvatures ( dig_shape, surfels, params );
251 auto cmap = SH3::getColorMap ( -0.5, 0.5, params );
252 auto colors = SH3::Colors ( def_surfels.size() );
253 auto match = SH3::getRangeMatch ( def_surfels, surfels );
254 auto normals = SH3::getMatchedRange ( ii_normals, match );
255 for ( SH3::Idx i = 0; i < colors.size(); i++ )
256 colors[ i ] = cmap( ii_mean_curv[ match[ i ] ] );
257 bool ok_H = SH3::saveOBJ(
surface, SH3::RealVectors(), colors,
"goursat-imp-H-ii.obj" );
259 ++nb; nbok += ( ok_H && ii_mean_curv.size() == ii_mean_curv2.size() ) ? 1 : 0;
263 trace.
beginBlock (
"Build polynomial shape -> save several projected quadrangulated surface and digitized boundaries." );
265 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
266 std::vector<double> gridsteps {0.5, 0.25, 0.125};
267 for (
auto h : gridsteps ) {
268 params(
"polynomial",
"goursat" )(
"gridstep", h );
269 auto implicit_shape = SH3::makeImplicitShape3D ( params );
270 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
271 auto binary_image = SH3::makeBinaryImage ( digitized_shape, params );
272 auto K = SH3::getKSpace( params );
273 auto embedder = SH3::getCellEmbedder(
K );
276 auto pointels = SH3::getPointelRange( c2i,
surface );
277 SH3::RealPoints pos( pointels.size() );
278 std::transform( pointels.cbegin(), pointels.cend(), pos.begin(),
279 [&] (
const SH3::Cell& c) { return h * embedder( c ); } );
280 auto ppos = SHG3::getPositions( implicit_shape, pos, params );
281 auto fname = std::string(
"goursat-quad-" ) + std::to_string( h ) + std::string(
".obj" );
282 bool ok = SH3::saveOBJ(
surface,
283 [&] (
const SH3::Cell& c){
return pos[ c2i[ c ] ];},
284 SH3::RealVectors(), SH3::Colors(),
286 auto proj_fname = std::string(
"goursat-quad-proj-" ) + std::to_string( h ) + std::string(
".obj" );
287 bool proj_ok = SH3::saveOBJ(
surface,
288 [&] (
const SH3::Cell& c){
return ppos[ c2i[ c ] ];},
289 SH3::RealVectors(), SH3::Colors(),
291 ++nb; nbok += ok ? 1 : 0;
292 ++nb; nbok += proj_ok ? 1 : 0;
297 trace.
beginBlock (
"Build polynomial shape -> digitize -> digital surface -> save primal surface and VCM normal field as obj." );
299 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
301 params(
"polynomial",
"goursat" )(
"gridstep", 0.5 )
302 (
"surfaceTraversal",
"Default" );
303 auto implicit_shape = SH3::makeImplicitShape3D ( params );
304 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
305 auto K = SH3::getKSpace( params );
306 auto binary_image = SH3::makeBinaryImage( digitized_shape, params );
308 auto surfels = SH3::getSurfelRange(
surface, params );
309 auto vcm_normals = SHG3::getVCMNormalVectors(
surface, surfels, params );
310 auto embedder = SH3::getSCellEmbedder(
K );
311 SH3::RealPoints positions( surfels.size() );
312 std::transform( surfels.cbegin(), surfels.cend(), positions.begin(),
313 [&] (
const SH3::SCell& c) { return embedder( c ); } );
314 bool ok = SH3::saveOBJ(
surface, vcm_normals, SH3::Colors(),
315 "goursat-primal-vcm.obj" );
316 bool ok2 = SH3::saveVectorFieldOBJ( positions, vcm_normals, 0.05, SH3::Colors(),
317 "goursat-primal-vcm-normals.obj",
318 SH3::Color( 0, 0, 0 ), SH3::Color::Red );
320 ++nb, nbok += ok ? 1 : 0;
321 ++nb, nbok += ok2 ? 1 : 0;
325 trace.
beginBlock (
"Build polynomial shape -> digitize -> extract ground-truth curvatures -> display in OBJ." );
327 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
329 params(
"polynomial",
"goursat" )(
"gridstep", 0.25 )(
"colormap",
"Tics" );
330 auto implicit_shape = SH3::makeImplicitShape3D ( params );
331 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
332 auto bimage = SH3::makeBinaryImage ( digitized_shape, params );
333 auto K = SH3::getKSpace( params );
334 auto surface = SH3::makeLightDigitalSurface( bimage,
K, params );
335 auto surfels = SH3::getSurfelRange(
surface, params );
336 auto k1 = SHG3::getFirstPrincipalCurvatures( implicit_shape,
K, surfels, params );
337 auto k2 = SHG3::getSecondPrincipalCurvatures( implicit_shape,
K, surfels, params );
338 auto d1 = SHG3::getFirstPrincipalDirections( implicit_shape,
K, surfels, params );
339 auto d2 = SHG3::getSecondPrincipalDirections( implicit_shape,
K, surfels, params );
340 auto embedder = SH3::getSCellEmbedder(
K );
341 SH3::RealPoints positions( surfels.size() );
342 std::transform( surfels.cbegin(), surfels.cend(), positions.begin(),
343 [&] (
const SH3::SCell& c) { return embedder( c ); } );
344 SH3::saveOBJ(
surface, SH3::RealVectors(), SH3::Colors(),
345 "goursat-primal.obj" );
347 auto cmap = SH3::getColorMap( -0.5, 0.5, params );
348 auto colors= SH3::Colors( surfels.size() );
349 std::transform( k1.cbegin(), k1.cend(), colors.begin(), cmap );
350 bool ok_k1 = SH3::saveOBJ(
surface, SH3::RealVectors(), colors,
"goursat-primal-k1.obj" );
351 bool ok_d1 = SH3::saveVectorFieldOBJ( positions, d1, 0.05, colors,
352 "goursat-primal-d1.obj", SH3::Color::Black );
353 std::transform( k2.cbegin(), k2.cend(), colors.begin(), cmap );
354 bool ok_k2 = SH3::saveOBJ(
surface, SH3::RealVectors(), colors,
"goursat-primal-k2.obj" );
355 bool ok_d2 = SH3::saveVectorFieldOBJ( positions, d2, 0.05, colors,
356 "goursat-primal-d2.obj", SH3::Color::Black );
357 ASSERT(ok_k1 && ok_d1 && ok_k2 && ok_d2);
362 trace.
beginBlock(
"Load mesh file -> estimate mean/gaussian/principal curvatures -> display in obj" );
365 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
366 params(
"r-radius", 0.1);
368 auto mesh = SH3::makeSurfaceMesh(examplesPath +
"samples/bunnyhead2.obj");
370 auto mcurv = SHG3::getCNCMeanCurvatures(mesh, params);
371 auto gcurv = SHG3::getCNCGaussianCurvatures(mesh, params);
372 auto [k1, k2, d1, d2] = SHG3::getCNCPrincipalCurvaturesAndDirections(mesh);
373 auto cmap = SH3::getColorMap( -1, 1, params );
375 auto mcolors = SH3::Colors( mcurv.size() );
376 std::transform( mcurv.cbegin(), mcurv.cend(), mcolors.begin(), cmap );
378 auto gcolors = SH3::Colors( gcurv.size() );
379 std::transform( gcurv.cbegin(), gcurv.cend(), gcolors.begin(), cmap );
381 auto k1colors = SH3::Colors( k1.size() );
382 std::transform( k1.begin(), k1.end(), k1colors.begin(), cmap);
384 auto k2colors = SH3::Colors( k2.size() );
385 std::transform( k2.begin(), k2.end(), k2colors.begin(), cmap);
387 bool ok_m = SH3::saveOBJ( mesh, SH3::RealVectors(), mcolors,
"bunnyhead2-meanCurvature.obj" );
388 bool ok_g = SH3::saveOBJ( mesh, SH3::RealVectors(), gcolors,
"bunnyhead2-gaussianCurvature.obj" );
389 bool ok_k1 = SH3::saveOBJ( mesh, SH3::RealVectors(), k1colors,
"bunnyhead2-firstPrincipalCurvature.obj" );
390 bool ok_k2 = SH3::saveOBJ( mesh, SH3::RealVectors(), k2colors,
"bunnyhead2-secondPrincpalCurvature.obj" );
400#if defined(DGTAL_WITH_EIGEN)
401 trace.
beginBlock (
"Load vol file -> build main digital surface -> II normals -> AT regularization -> save OBJ with colored normals." );
403 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
405 auto al_capone = SH3::makeBinaryImage( examplesPath +
"samples/Al.100.vol", params );
406 auto K = SH3::getKSpace( al_capone );
407 auto surface = SH3::makeLightDigitalSurface( al_capone,
K, params );
408 auto surfels = SH3::getSurfelRange(
surface, params );
409 auto ii_normals = SHG3::getIINormalVectors( al_capone, surfels, params );
410 auto linels = SH3::getCellRange(
surface, 1 );
411 auto uembedder = SH3::getCellEmbedder(
K );
412 SH3::Scalars features( linels.size() );
413 auto at_normals = SHG3::getATVectorFieldApproximation( features, linels.cbegin(), linels.cend(),
415 ii_normals, params );
417 SH3::Colors colors( surfels.size() );
418 for (
size_t i = 0; i < surfels.size(); i++ )
419 colors[ i ] = SH3::Color( (
unsigned char) 255.0*fabs( at_normals[ i ][ 0 ] ),
420 (
unsigned char) 255.0*fabs( at_normals[ i ][ 1 ] ),
421 (
unsigned char) 255.0*fabs( at_normals[ i ][ 2 ] ) );
422 bool ok1 = SH3::saveOBJ(
surface, SH3::RealVectors(), SH3::Colors(),
"al-surface.obj" );
423 bool ok2 = SH3::saveOBJ(
surface, at_normals, colors,
"al-colored-at-normals.obj" );
427 for (
size_t i = 0; i < linels.size(); i++ )
429 if ( features[ i ] < 0.5 )
431 const SH3::Cell linel = linels[ i ];
433 const SH3::Cell p0 =
K.
uIncident( linel, d,
false );
434 const SH3::Cell p1 =
K.
uIncident( linel, d,
true );
435 f0.push_back( uembedder( p0 ) );
436 f1.push_back( uembedder( p1 ) - uembedder( p0 ) );
439 bool ok3 = SH3::saveVectorFieldOBJ( f0, f1, 0.1, SH3::Colors(),
441 SH3::Color( 0, 0, 0 ), SH3::Color::Red );
443 ++nb; nbok += ok1 ? 1 : 0;
444 ++nb; nbok += ok2 ? 1 : 0;
445 ++nb; nbok += ok3 ? 1 : 0;
451#if DGTAL_WITH_POLYSCOPE
452 trace.
beginBlock(
"Load vol file -> Compute VoronoiMap -> Display in Viewer" );
454 auto params = SH3::defaultParameters() | SHG3::defaultParameters();
456 auto bimage = SH3::makeBinaryImage( examplesPath +
"samples/Al.100.vol", params );
457 auto domain = bimage->domain();
460 std::vector<SH3::Point> sites;
463 std::back_inserter(sites),
467 auto vmap1 = SHG3::getDistanceTransformation<1>(bimage->domain(), sites, params);
468 auto vmap2 = SHG3::getDistanceTransformation<2>(bimage->domain(), sites, params);
478 "L1 distance", vmap1(*it)
479 ),
"L2 distance", vmap2(*it)
491 trace.
info() << nbok <<
"/" << nb <<
" passed tests." << std::endl;