DGtal 2.1.0
Loading...
Searching...
No Matches
Shortcuts.h
1
17#pragma once
18
31#if defined(Shortcuts_RECURSES)
32#error Recursive header files inclusion detected in Shortcuts.h
33#else // defined(Shortcuts_RECURSES)
35#define Shortcuts_RECURSES
36
37#if !defined Shortcuts_h
39#define Shortcuts_h
40
42// Inclusions
43#include <iterator>
44#include <optional>
45
46#include "DGtal/base/Common.h"
47#include "DGtal/base/CountedPtr.h"
48#include "DGtal/kernel/domains/HyperRectDomain.h"
49#include "DGtal/kernel/RegularPointEmbedder.h"
50#include "DGtal/math/MPolynomial.h"
51#include "DGtal/math/Statistic.h"
52#include "DGtal/images/ImageContainerBySTLVector.h"
53#include "DGtal/images/IntervalForegroundPredicate.h"
54#include "DGtal/images/ImageLinearCellEmbedder.h"
55#include "DGtal/shapes/implicit/ImplicitPolynomial3Shape.h"
56#include "DGtal/shapes/GaussDigitizer.h"
57#include "DGtal/shapes/ShapeGeometricFunctors.h"
58#include "DGtal/shapes/MeshHelpers.h"
59#include "DGtal/topology/CCellularGridSpaceND.h"
60#include "DGtal/topology/LightImplicitDigitalSurface.h"
61#include "DGtal/topology/SetOfSurfels.h"
62#include "DGtal/topology/DigitalSurface.h"
63#include "DGtal/topology/IndexedDigitalSurface.h"
64#include "DGtal/topology/SurfelAdjacency.h"
65#include "DGtal/topology/CCellEmbedder.h"
66#include "DGtal/topology/CanonicCellEmbedder.h"
67#include "DGtal/topology/CanonicSCellEmbedder.h"
68#include "DGtal/topology/helpers/Surfaces.h"
69#include "DGtal/geometry/volumes/KanungoNoise.h"
70#include "DGtal/shapes/Mesh.h"
71#include "DGtal/io/Color.h"
72#include "DGtal/io/colormaps/GradientColorMap.h"
73#include "DGtal/io/colormaps/TickedColorMap.h"
74#include "DGtal/io/readers/MPolynomialReader.h"
75#include "DGtal/io/readers/GenericReader.h"
76#include "DGtal/io/readers/SurfaceMeshReader.h"
77#include "DGtal/io/writers/GenericWriter.h"
78#include "DGtal/io/writers/MeshWriter.h"
79#include "DGtal/graph/BreadthFirstVisitor.h"
80#include "DGtal/graph/DepthFirstVisitor.h"
81#include "DGtal/graph/GraphVisitorRange.h"
82#include "DGtal/helpers/Parameters.h"
84
85namespace DGtal
86{
87
89 // template class Shortcuts
100 template < typename TKSpace >
102 {
104
105 // ----------------------- Usual space types --------------------------------------
106 public:
108 typedef TKSpace KSpace;
110 typedef typename KSpace::Space Space;
112 typedef typename Space::Integer Integer;
114 typedef typename Space::Point Point;
116 typedef typename Space::Vector Vector;
120 typedef typename Space::RealPoint RealPoint;
126 typedef unsigned char GrayScale;
127
128 // ----------------------- Shortcut types --------------------------------------
129 public:
146 typedef typename KSpace::SurfelSet SurfelSet;
151 typedef ::DGtal::DigitalSurface< LightSurfaceContainer > LightDigitalSurface;
155 typedef ::DGtal::DigitalSurface< ExplicitSurfaceContainer > DigitalSurface;
169 typedef std::set< IdxSurfel > IdxSurfelSet;
170 typedef std::vector< SCell > SCellRange;
171 typedef std::vector< Cell > CellRange;
174 typedef std::vector< IdxSurfel > IdxSurfelRange;
175 typedef std::vector< Scalar > Scalars;
176 typedef std::vector< RealVector > RealVectors;
177 typedef std::vector< RealPoint > RealPoints;
178 typedef IdxVertex Idx;
179 typedef std::vector< IdxVertex > IdxRange;
180
181 typedef ::DGtal::Mesh<RealPoint> Mesh;
182 typedef ::DGtal::TriangulatedSurface<RealPoint> TriangulatedSurface;
183 typedef ::DGtal::PolygonalSurface<RealPoint> PolygonalSurface;
184 typedef ::DGtal::SurfaceMesh<RealPoint,RealPoint> SurfaceMesh;
185 typedef std::map<Surfel, IdxSurfel> Surfel2Index;
186 typedef std::map<Cell, IdxVertex> Cell2Index;
187
189 typedef std::vector< Color > Colors;
192
193 // ----------------------- Static services --------------------------------------
194 public:
195
196 // ----------------------- General static services ------------------------------
197 public:
198
211
212 // ----------------------- ImplicitShape3D static services ------------------------
213 public:
214
232 static std::map< std::string, std::string >
234 {
235 std::vector< std::pair< std::string, std::string > >
236 Ps = { { "sphere1", "x^2+y^2+z^2-1" },
237 { "sphere9", "x^2+y^2+z^2-81" },
238 { "ellipsoid", "3*x^2+2*y^2+z^2-90" },
239 { "cylinder", "x^2+2*z^2-90" },
240 { "torus", "(x^2+y^2+z^2+6*6-2*2)^2-4*6*6*(x^2+y^2)" },
241 { "rcube", "x^4+y^4+z^4-6561" },
242 { "goursat", "-1*(8-0.03*x^4-0.03*y^4-0.03*z^4+2*x^2+2*y^2+2*z^2)" },
243 { "goursat-hole", "x^4+y^4+z^4-2*4*(x^2+y^2+z^2)+2*4*4-2" },
244 { "distel", "10000-(x^2+y^2+z^2+1000*(x^2+y^2)*(x^2+z^2)*(y^2+z^2))"},
245 { "leopold", "(x^2*y^2*z^2+4*x^2+4*y^2+3*z^2)-100" },
246 { "diabolo", "x^2-(y^2+z^2)^2" },
247 { "heart", "-1*(x^2+2.25*y^2+z^2-1)^3+x^2*z^3+0.1125*y^2*z^3" },
248 { "crixxi", "-0.9*(y^2+z^2-1)^2-(x^2+y^2-1)^3" } };
249 std::map< std::string, std::string > L;
250 for ( auto p : Ps )
251 L[ p.first ] = p.second;
252 return L;
253 }
254
263 {
264 return Parameters
265 ( "polynomial", "sphere1" )
266 ( "projectionMaxIter", 20 )
267 ( "projectionAccuracy", 0.0001 )
268 ( "projectionGamma", 0.5 );
269 }
270
280 {
282 std::string poly_str = params[ "polynomial" ].as<std::string>();
283 // Recognizes specific strings as polynomials.
284 auto PL = getPolynomialList();
285 if ( PL[ poly_str ] != "" ) poly_str = PL[ poly_str ];
286 ScalarPolynomial poly;
287 Polynomial3Reader reader;
288 std::string::const_iterator iter
289 = reader.read( poly, poly_str.begin(), poly_str.end() );
290 if ( iter != poly_str.end() )
291 {
292 trace.error() << "[Shortcuts::makeImplicitShape3D]"
293 << " ERROR reading polynomial: I read only <"
294 << poly_str.substr( 0, iter - poly_str.begin() )
295 << ">, and I built P=" << poly << std::endl;
296 }
297 return CountedPtr<ImplicitShape3D>( new ImplicitShape3D( poly ) );
298 }
299
300 // ----------------------- KSpace static services ------------------------------
301 public:
302
309 {
310 return Parameters
311 ( "closed", 1 )
312 ( "gridsizex", 1.0 )
313 ( "gridsizey", 1.0 )
314 ( "gridsizez", 1.0 );
315 }
316
329 static KSpace getKSpace( const Point& low, const Point& up,
330 Parameters params = parametersKSpace() )
331 {
332 int closed = params[ "closed" ].as<int>();
333 KSpace K;
334 if ( ! K.init( low, up, closed ) )
335 trace.error() << "[Shortcuts::getKSpace]"
336 << " Error building Khalimsky space K=" << K << std::endl;
337 return K;
338 }
339
352 Parameters params = parametersKSpace() )
353 {
354 int closed = params[ "closed" ].as<int>();
355 KSpace K;
356 if ( ! K.init( bimage->domain().lowerBound(),
357 bimage->domain().upperBound(),
358 closed ) )
359 trace.error() << "[Shortcuts::getKSpace]"
360 << " Error building Khalimsky space K=" << K << std::endl;
361 return K;
362 }
363
376 Parameters params = parametersKSpace() )
377 {
378 int closed = params[ "closed" ].as<int>();
379 KSpace K;
380 if ( ! K.init( gimage->domain().lowerBound(),
381 gimage->domain().upperBound(),
382 closed ) )
383 trace.error() << "[Shortcuts::getKSpace]"
384 << " Error building Khalimsky space K=" << K << std::endl;
385 return K;
386 }
387
391 template <typename TDigitalSurfaceContainer>
392 static KSpace
395 {
396 return surface->container().space();
397 }
398
402 template <typename TDigitalSurfaceContainer>
403 static KSpace
409
413 template <typename TDigitalSurfaceContainer>
414 static const KSpace&
417 {
418 return surface->container().space();
419 }
420
424 template <typename TDigitalSurfaceContainer>
425 static const KSpace&
431
436 {
438 }
439
444 {
446 }
447
448
449 // ----------------------- DigitizedImplicitShape3D static services --------------
450 public:
451
459 {
460 return Parameters
461 ( "minAABB", -10.0 )
462 ( "maxAABB", 10.0 )
463 ( "gridstep", 1.0 )
464 ( "offset", 5.0 );
465 }
466
467
482 static KSpace
485 {
486 Scalar min_x = params[ "minAABB" ].as<Scalar>();
487 Scalar max_x = params[ "maxAABB" ].as<Scalar>();
488 Scalar h = params[ "gridstep" ].as<Scalar>();
489 Scalar offset = params[ "offset" ].as<Scalar>();
490 bool closed = params[ "closed" ].as<int>();
491 RealPoint p1( min_x - offset * h, min_x - offset * h, min_x - offset * h );
492 RealPoint p2( max_x + offset * h, max_x + offset * h, max_x + offset * h );
494 dshape->init( p1, p2, h );
495 Domain domain = dshape->getDomain();
496 KSpace K;
497 if ( ! K.init( domain.lowerBound(), domain.upperBound(), closed ) )
498 trace.error() << "[Shortcuts::getKSpace]"
499 << " Error building Khalimsky space K=" << K << std::endl
500 << "Note: if you use decimal values, check your locale for decimal point '.' or ','."
501 << std::endl;
502 return K;
503 }
504
522 {
523 Scalar min_x = params[ "minAABB" ].as<Scalar>();
524 Scalar max_x = params[ "maxAABB" ].as<Scalar>();
525 Scalar h = params[ "gridstep" ].as<Scalar>();
526 Scalar offset = params[ "offset" ].as<Scalar>();
527 RealPoint p1( min_x - offset * h, min_x - offset * h, min_x - offset * h );
528 RealPoint p2( max_x + offset * h, max_x + offset * h, max_x + offset * h );
530 dshape->attach( shape );
531 dshape->init( p1, p2, h );
532 return dshape;
533 }
534
535
536 // ----------------------- BinaryImage static services --------------------------
537 public:
538
545 {
546 return Parameters
547 ( "noise", 0.0 )
548 ( "thresholdMin", 0 )
549 ( "thresholdMax", 255 );
550 }
551
558 makeBinaryImage( Domain shapeDomain )
559 {
560 return CountedPtr<BinaryImage>( new BinaryImage( shapeDomain ) );
561 }
562
575 {
576 return makeBinaryImage( shape_digitization,
577 shape_digitization->getDomain(),
578 params );
579 }
580
594 Domain shapeDomain,
596 {
597 const Scalar noise = params[ "noise" ].as<Scalar>();
598 CountedPtr<BinaryImage> img ( new BinaryImage( shapeDomain ) );
599 if ( noise <= 0.0 )
600 {
601 std::transform( shapeDomain.begin(), shapeDomain.end(),
602 img->begin(),
603 [&shape_digitization]
604 ( const Point& p ) { return (*shape_digitization)(p); } );
605 }
606 else
607 {
609 KanungoPredicate noisy_dshape( *shape_digitization, shapeDomain, noise );
610 std::transform( shapeDomain.begin(), shapeDomain.end(),
611 img->begin(),
612 [&noisy_dshape] ( const Point& p ) { return noisy_dshape(p); } );
613 }
614 return img;
615 }
616
627 {
628 const Scalar noise = params[ "noise" ].as<Scalar>();
629 if ( noise <= 0.0 ) return bimage;
630 typedef KanungoNoise< BinaryImage, Domain > KanungoPredicate;
631 const Domain shapeDomain = bimage->domain();
632 CountedPtr<BinaryImage> img ( new BinaryImage( shapeDomain ) );
633 KanungoPredicate noisy_dshape( *bimage, shapeDomain, noise );
634 std::transform( shapeDomain.begin(), shapeDomain.end(),
635 img->begin(),
636 [&noisy_dshape] ( const Point& p ) { return noisy_dshape(p); } );
637 return img;
638 }
639
653 ( std::string input,
655 {
656 int thresholdMin = params["thresholdMin"].as<int>();
657 int thresholdMax = params["thresholdMax"].as<int>();
659 Domain domain = image.domain();
661 ThresholdedImage tImage( image, thresholdMin, thresholdMax );
663 std::transform( domain.begin(), domain.end(),
664 img->begin(),
665 [tImage] ( const Point& p ) { return tImage(p); } );
666 return makeBinaryImage( img, params );
667 }
668
669 // These types helps to disambiguate between makeBinaryImage with a simple
670 // position vector and nested vectors. These are also used for makeGrayScaleImage
671
672 template<typename T>
673 struct is_double_nested_container : std::false_type {};
674
675 template<typename T, template<class...> class C, template<class...> class D>
676 struct is_double_nested_container<C<D<T>>> : std::true_type {};
677
688 template<typename T, typename __U = std::enable_if_t<std::is_arithmetic_v<T>>>
691 ( const std::vector<T>& values,
692 const Domain& d )
693 {
695
696 size_t i = 0;
697 for (auto it = d.begin(); it != d.end(); ++i, ++it)
698 {
699 image->setValue(*it, static_cast<bool>(values[i]));
700 }
701
702 return image;
703 }
704
714 template<
715 typename T,
716 template<class...> class C1, // Allow for mix of array/vector/other contiguous arrays
717 template<class...> class C2, // Allow for mix of array/vector/other contiguous arrays
718 template<class...> class C3> // Allow for mix of array/vector/other contiguous arrays
721 ( const C1<C2<C3<T>>>& values,
722 std::optional<Domain> override_domain = std::nullopt)
723 {
724 Domain d;
725 if (override_domain.has_value())
726 {
727 d = override_domain.value();
728 }
729 else if (values.size() != 0)
730 {
731 if (values[0].size() != 0)
732 {
733 if (values[0][0].size() != 0)
734 {
735 d = Domain(Point(0, 0, 0), Point(values.size(), values[0].size(), values[0][0].size()));
736 }
737 }
738 }
739
741 Point begin = d.lowerBound();
742 for (size_t i = 0; i < values.size(); ++i)
743 {
744 for (size_t j = 0; j < values[i].size(); ++j)
745 {
746 for (size_t k = 0; k < values[i][j].size(); ++k)
747 {
748 Point p = begin + Point(i, j, k);
749 image->setValue(p, static_cast<bool>(values[i][j][k]));
750 }
751 }
752 }
753
754 return image;
755 }
756
765 template<typename T, std::enable_if_t<!is_double_nested_container<T>::value, int> = 0>
768 ( const std::vector<T>& positions,
769 std::optional<Domain> override_domain = std::nullopt)
770 {
771 Domain d;
772 if (override_domain.has_value())
773 {
774 d = override_domain.value();
775 }
776 else if (positions.size() != 0)
777 {
778 Point lb(positions[0][0], positions[0][1], positions[0][2]);
779 Point ub(positions[0][0], positions[0][1], positions[0][2]);
780
781 for (size_t i = 0; i < positions.size(); ++i)
782 {
783 lb[0] = std::min(lb[0], static_cast<typename Point::Component>(positions[i][0]));
784 lb[1] = std::min(lb[1], static_cast<typename Point::Component>(positions[i][1]));
785 lb[2] = std::min(lb[2], static_cast<typename Point::Component>(positions[i][2]));
786
787 ub[0] = std::max(ub[0], static_cast<typename Point::Component>(positions[i][0]));
788 ub[1] = std::max(ub[1], static_cast<typename Point::Component>(positions[i][1]));
789 ub[2] = std::max(ub[2], static_cast<typename Point::Component>(positions[i][2]));
790 }
791
792 d = Domain(lb, ub);
793 }
794
796 for (size_t i = 0; i < positions.size(); ++i)
797 {
798 // Builds a points for generality, T may not be a PointVector instance
799 Point p({positions[i][0], positions[i][1], positions[i][2]});
800 image->setValue(p, true);
801 }
802 return image;
803 }
804
818 ( CountedPtr<GrayScaleImage> gray_scale_image,
820 {
821 int thresholdMin = params["thresholdMin"].as<int>();
822 int thresholdMax = params["thresholdMax"].as<int>();
823 Domain domain = gray_scale_image->domain();
825 ThresholdedImage tImage( *gray_scale_image, thresholdMin, thresholdMax );
827 std::transform( domain.begin(), domain.end(),
828 img->begin(),
829 [tImage] ( const Point& p ) { return tImage(p); } );
830 return makeBinaryImage( img, params );
831 }
832
833
839 static bool
841 ( CountedPtr<BinaryImage> bimage, std::string output )
842 {
843 auto gray_scale_image = makeGrayScaleImage( bimage );
844 return saveGrayScaleImage( gray_scale_image, output );
845 }
846
847
848 // ----------------------- GrayScaleImage static services -------------------------
849 public:
850
857 {
858 return Parameters
859 ( "qShift", 128.0 )
860 ( "qSlope", 1.0 );
861 }
862
870 {
871 return CountedPtr<GrayScaleImage>( new GrayScaleImage( aDomain ) );
872 }
873
882 ( std::string input )
883 {
886 }
887
897 std::function< GrayScale( bool ) > const & bool2grayscale
898 = [] ( bool v ) { return v ? (unsigned char) 255 : (unsigned char) 0; }
899 // JOL: (GrayScale) was not working with visual C++: error C2065
900 )
901 {
902 const Domain domain = binary_image->domain();
903 CountedPtr<GrayScaleImage> gray_scale_image( new GrayScaleImage( domain ) );
904 std::transform( binary_image->begin(), binary_image->end(),
905 gray_scale_image->begin(),
906 bool2grayscale );
907 return gray_scale_image;
908 }
909
915 static bool
917 ( CountedPtr<GrayScaleImage> gray_scale_image, std::string output )
918 {
920 ::exportFile( output, *gray_scale_image );
921 }
922
923
937 ( CountedPtr<FloatImage> fimage,
939 {
940 float qShift = params[ "qShift" ].as<float>();
941 float qSlope = params[ "qSlope" ].as<float>();
942 std::function< unsigned char( float ) > f
943 = [qShift,qSlope] (float v)
944 { return (unsigned char) std::min( 255.0f, std::max( 0.0f, qSlope * v + qShift ) ); };
945 Domain domain = fimage->domain();
946 auto gimage = makeGrayScaleImage( domain );
947 auto it = gimage->begin();
948 for ( auto p : domain )
949 {
950 float val = (*fimage)( p );
951 *it++ = f( val );
952 }
953 return gimage;
954 }
955
971 {
972 double qShift = params[ "qShift" ].as<double>();
973 double qSlope = params[ "qSlope" ].as<double>();
974 std::function< unsigned char( double ) > f
975 = [qShift,qSlope] (double v)
976 { return (unsigned char) std::min( 255.0, std::max( 0.0, qSlope * v + qShift ) ); };
977 Domain domain = fimage->domain();
978 auto gimage = makeGrayScaleImage( domain );
979 auto it = gimage->begin();
980 for ( auto p : domain )
981 {
982 double val = (*fimage)( p );
983 *it++ = f( val );
984 }
985 return gimage;
986 }
987
997 template<typename T, typename __U = std::enable_if_t<std::is_arithmetic_v<T>>>
1000 ( const std::vector<T>& values,
1001 const Domain& d )
1002 {
1004
1005 size_t i = 0;
1006 for (auto it = d.begin(); it != d.end(); ++i, ++it)
1007 {
1008 image->setValue(*it, static_cast<GrayScale>(values[i]));
1009 }
1010
1011 return image;
1012 }
1013
1022 template<
1023 typename T,
1024 template<class...> class C1, // Allow for mix of array/vector/other contiguous arrays
1025 template<class...> class C2, // Allow for mix of array/vector/other contiguous arrays
1026 template<class...> class C3> // Allow for mix of array/vector/other contiguous arrays
1029 ( const C1<C2<C3<T>>>& values,
1030 std::optional<Domain> override_domain = std::nullopt)
1031 {
1032 Domain d;
1033 if (override_domain.has_value())
1034 {
1035 d = override_domain.value();
1036 }
1037 else if (values.size() != 0)
1038 {
1039 if (values[0].size() != 0)
1040 {
1041 if (values[0][0].size() != 0)
1042 {
1043 d = Domain(Point(0, 0, 0), Point(values.size(), values[0].size(), values[0][0].size()));
1044 }
1045 }
1046 }
1047
1049 Point begin = d.lowerBound();
1050 for (size_t i = 0; i < values.size(); ++i)
1051 {
1052 for (size_t j = 0; j < values[i].size(); ++j)
1053 {
1054 for (size_t k = 0; k < values[i][j].size(); ++k)
1055 {
1056 Point p = begin + Point(i, j, k);
1057 image->setValue(p, static_cast<GrayScale>(values[i][j][k]));
1058 }
1059 }
1060 }
1061
1062 return image;
1063 }
1064
1074 template<typename T, typename U, std::enable_if_t<!is_double_nested_container<T>::value, int> = 0>
1077 ( const std::vector<T>& positions,
1078 const std::vector<U>& values,
1079 std::optional<Domain> override_domain = std::nullopt)
1080 {
1081 Domain d;
1082 if (override_domain.has_value())
1083 {
1084 d = override_domain.value();
1085 }
1086 else if (positions.size() != 0)
1087 {
1088 Point lb(positions[0][0], positions[0][1], positions[0][2]);
1089 Point ub(positions[0][0], positions[0][1], positions[0][2]);
1090
1091 for (size_t i = 0; i < positions.size(); ++i)
1092 {
1093 lb[0] = std::min(lb[0], static_cast<typename Point::Component>(positions[i][0]));
1094 lb[1] = std::min(lb[1], static_cast<typename Point::Component>(positions[i][1]));
1095 lb[2] = std::min(lb[2], static_cast<typename Point::Component>(positions[i][2]));
1096
1097 ub[0] = std::max(ub[0], static_cast<typename Point::Component>(positions[i][0]));
1098 ub[1] = std::max(ub[1], static_cast<typename Point::Component>(positions[i][1]));
1099 ub[2] = std::max(ub[2], static_cast<typename Point::Component>(positions[i][2]));
1100 }
1101
1102 d = Domain(lb, ub);
1103 }
1104
1106 for (size_t i = 0; i < positions.size(); ++i)
1107 {
1108 // Builds a points for generality, T may not be a PointVector instance
1109 Point p({positions[i][0], positions[i][1], positions[i][2]});
1110 image->setValue(p, static_cast<GrayScale>(values[i]));
1111 }
1112 return image;
1113 }
1114
1115
1116 // ----------------------- FloatImage static services -------------------------
1117 public:
1118
1126 {
1127 return CountedPtr<FloatImage>( new FloatImage( aDomain ) );
1128 }
1129
1138 ( std::string input )
1139 {
1141 return CountedPtr<FloatImage>( new FloatImage( image ) );
1142 }
1143
1161 {
1162 Scalar min_x = params[ "minAABB" ].as<Scalar>();
1163 Scalar max_x = params[ "maxAABB" ].as<Scalar>();
1164 Scalar h = params[ "gridstep" ].as<Scalar>();
1165 Scalar offset = params[ "offset" ].as<Scalar>();
1166 RealPoint p1( min_x - offset * h, min_x - offset * h, min_x - offset * h );
1167 RealPoint p2( max_x + offset * h, max_x + offset * h, max_x + offset * h );
1169 dshape->attach( shape );
1170 dshape->init( p1, p2, h );
1171 Domain domain = dshape->getDomain();
1172 auto fimage = makeFloatImage( domain );
1173 auto it = fimage->begin();
1174 for ( auto p : domain )
1175 {
1176 float val = (float) (*shape)( p );
1177 *it++ = val;
1178 }
1179 return fimage;
1180 }
1181
1182 // ----------------------- DoubleImage static services -------------------------
1183 public:
1184
1192 {
1193 return CountedPtr<DoubleImage>( new DoubleImage( aDomain ) );
1194 }
1195
1204 ( std::string input )
1205 {
1207 return CountedPtr<DoubleImage>( new DoubleImage( image ) );
1208 }
1209
1227 {
1228 Scalar min_x = params[ "minAABB" ].as<Scalar>();
1229 Scalar max_x = params[ "maxAABB" ].as<Scalar>();
1230 Scalar h = params[ "gridstep" ].as<Scalar>();
1231 Scalar offset = params[ "offset" ].as<Scalar>();
1232 RealPoint p1( min_x - offset * h, min_x - offset * h, min_x - offset * h );
1233 RealPoint p2( max_x + offset * h, max_x + offset * h, max_x + offset * h );
1235 dshape->attach( shape );
1236 dshape->init( p1, p2, h );
1237 Domain domain = dshape->getDomain();
1238 auto fimage = makeDoubleImage( domain );
1239 auto it = fimage->begin();
1240 for ( auto p : domain )
1241 {
1242 double val = (double) (*shape)( p );
1243 *it++ = val;
1244 }
1245 return fimage;
1246 }
1247
1248 // ----------------------- DigitalSurface static services ------------------------
1249 public:
1250
1258 {
1259 return Parameters
1260 ( "surfelAdjacency", 0 )
1261 ( "nbTriesToFindABel", 100000 )
1262 ( "surfaceComponents", "AnyBig" )
1263 ( "surfaceTraversal", "Default" );
1264 }
1265
1269 template <typename TDigitalSurfaceContainer>
1276
1280 template <typename TDigitalSurfaceContainer>
1287
1291 template <typename TDigitalSurfaceContainer>
1298
1302 template <typename TDigitalSurfaceContainer>
1309
1323 ( CountedPtr<BinaryImage> bimage,
1324 const KSpace& K,
1325 const Parameters& params = parametersDigitalSurface() )
1326 {
1327 bool surfel_adjacency = params[ "surfelAdjacency" ].as<int>();
1328 int nb_tries_to_find_a_bel = params[ "nbTriesToFindABel" ].as<int>();
1329 SurfelAdjacency< KSpace::dimension > surfAdj( surfel_adjacency );
1330
1331 // We have to search for a surfel that belongs to a big connected component.
1333 Surfel bel;
1334 Scalar minsize = bimage->extent().norm();
1335 unsigned int nb_surfels = 0;
1336 unsigned int tries = 0;
1337 do
1338 {
1339 try { // Search initial bel
1340 bel = Surfaces<KSpace>::findABel( K, *bimage, nb_tries_to_find_a_bel );
1341 } catch (DGtal::InputException& e) {
1342 trace.error() << "[Shortcuts::makeLightDigitalSurface]"
1343 << " ERROR Unable to find bel. " << e << std::endl;
1344 return ptrSurface;
1345 }
1346 // this pointer will be acquired by the surface.
1347 LightSurfaceContainer* surfContainer
1348 = new LightSurfaceContainer( K, *bimage, surfAdj, bel );
1350 ( new LightDigitalSurface( surfContainer ) ); // acquired
1351 nb_surfels = ptrSurface->size();
1352 }
1353 while ( ( nb_surfels < 2 * minsize ) && ( tries++ < 150 ) );
1354 if( tries >= 150 )
1355 trace.warning() << "[Shortcuts::makeLightDigitalSurface]"
1356 << "ERROR cannot find a proper bel in a big enough component."
1357 << std::endl;
1358 return ptrSurface;
1359 }
1360
1378 static std::vector< CountedPtr<LightDigitalSurface> >
1380 ( CountedPtr<BinaryImage> bimage,
1381 const KSpace& K,
1382 const Parameters& params = parametersDigitalSurface() )
1383 {
1384 SurfelRange surfel_reps;
1385 return makeLightDigitalSurfaces( surfel_reps, bimage, K, params );
1386 }
1387
1408 static std::vector< CountedPtr<LightDigitalSurface> >
1410 ( SurfelRange& surfel_reps,
1412 const KSpace& K,
1413 const Parameters& params = parametersDigitalSurface() )
1414 {
1415 std::vector< CountedPtr<LightDigitalSurface> > result;
1416 std::string component = params[ "surfaceComponents" ].as<std::string>();
1417 if ( component == "AnyBig" )
1418 {
1419 result.push_back( makeLightDigitalSurface( bimage, K, params ) );
1420 surfel_reps.push_back( *( result[ 0 ]->begin() ) );
1421 return result;
1422 }
1423 bool surfel_adjacency = params[ "surfelAdjacency" ].as<int>();
1424 SurfelAdjacency< KSpace::dimension > surfAdj( surfel_adjacency );
1425 // Extracts all boundary surfels
1426 SurfelSet all_surfels;
1427 Surfaces<KSpace>::sMakeBoundary( all_surfels, K, *bimage,
1428 K.lowerBound(), K.upperBound() );
1429 // Builds all connected components of surfels.
1430 SurfelSet marked_surfels;
1432 for ( auto bel : all_surfels )
1433 {
1434 if ( marked_surfels.count( bel ) != 0 ) continue;
1435 surfel_reps.push_back( bel );
1436 LightSurfaceContainer* surfContainer
1437 = new LightSurfaceContainer( K, *bimage, surfAdj, bel );
1439 ( new LightDigitalSurface( surfContainer ) ); // acquired
1440 // mark all surfels of the surface component.
1441 marked_surfels.insert( ptrSurface->begin(), ptrSurface->end() );
1442 // add surface component to result.
1443 result.push_back( ptrSurface );
1444 }
1445 return result;
1446 }
1447
1448
1467 template <typename TPointPredicate>
1471 const KSpace& K,
1472 const Parameters& params = parametersDigitalSurface() )
1473 {
1474 SurfelSet all_surfels;
1475 bool surfel_adjacency = params[ "surfelAdjacency" ].as<int>();
1476 SurfelAdjacency< KSpace::dimension > surfAdj( surfel_adjacency );
1477 // Extracts all boundary surfels
1478 Surfaces<KSpace>::sMakeBoundary( all_surfels, K, *bimage,
1479 K.lowerBound(), K.upperBound() );
1480 ExplicitSurfaceContainer* surfContainer
1481 = new ExplicitSurfaceContainer( K, surfAdj, all_surfels );
1483 ( new DigitalSurface( surfContainer ) ); // acquired
1484 }
1485
1486
1501 ( CountedPtr<IdxDigitalSurface> idx_surface,
1502 const Parameters& params = parametersDigitalSurface() )
1503 {
1504 bool surfel_adjacency = params[ "surfelAdjacency" ].as<int>();
1505 const KSpace& K = refKSpace( idx_surface );
1506 SurfelAdjacency< KSpace::dimension > surfAdj( surfel_adjacency );
1507 auto all_idx_surfels
1508 = getIdxSurfelRange( idx_surface, Parameters( "surfaceTraversal", "Default" ) );
1509 auto idx2surfel = idx_surface->surfels();
1510 SurfelSet all_surfels;
1511 for ( auto idx : all_idx_surfels ) all_surfels.insert( idx2surfel[ idx ] );
1512 ExplicitSurfaceContainer* surfContainer
1513 = new ExplicitSurfaceContainer( K, surfAdj, all_surfels );
1515 ( new DigitalSurface( surfContainer ) ); // acquired
1516 }
1517
1536 ( CountedPtr<BinaryImage> bimage,
1537 const KSpace& K,
1538 const Parameters& params = parametersDigitalSurface() )
1539 {
1540 std::string component = params[ "surfaceComponents" ].as<std::string>();
1541 SurfelSet surfels;
1542 if ( component == "AnyBig" )
1543 {
1544 auto light_surface = makeLightDigitalSurface( bimage, K, params );
1545 surfels.insert( light_surface->begin(), light_surface->end() );
1546 }
1547 else if ( component == "All" )
1548 {
1549 Surfaces<KSpace>::sMakeBoundary( surfels, K, *bimage,
1550 K.lowerBound(), K.upperBound() );
1551 }
1552 return makeIdxDigitalSurface( surfels, K, params );
1553 }
1554
1566 template <typename TSurfelRange>
1569 ( const TSurfelRange& surfels,
1571 const Parameters& params = parametersDigitalSurface() )
1572 {
1573 bool surfel_adjacency = params[ "surfelAdjacency" ].as<int>();
1574 SurfelAdjacency< KSpace::dimension > surfAdj( surfel_adjacency );
1575 // Build indexed digital surface.
1577 ( new ExplicitSurfaceContainer( K, surfAdj, surfels ) );
1579 ( new IdxDigitalSurface() );
1580 bool ok = ptrSurface->build( ptrSurfContainer );
1581 if ( !ok )
1582 trace.warning() << "[Shortcuts::makeIdxDigitalSurface]"
1583 << " Error building indexed digital surface." << std::endl;
1584 return ptrSurface;
1585 }
1586
1599 template <typename TDigitalSurfaceContainer>
1603 const Parameters& params = parametersDigitalSurface() )
1604 {
1605 const KSpace& K = refKSpace( surface );
1606 SurfelSet surfels;
1607 surfels.insert( surface->begin(), surface->end() );
1608 return makeIdxDigitalSurface( surfels, K, params );
1609 }
1610
1625 ( const std::vector< CountedPtr<LightDigitalSurface> >& surfaces,
1626 const Parameters& params = parametersDigitalSurface() )
1627 {
1628 if ( surfaces.empty() ) return CountedPtr<IdxDigitalSurface>( 0 );
1629 const KSpace& K = surfaces[ 0 ]->container().space();
1630 SurfelSet surfels;
1631 for ( std::size_t i = 0; i < surfaces.size(); ++i )
1632 {
1633 const KSpace& Ki = surfaces[ i ]->container().space();
1634 if ( ( Ki.lowerBound() != K.lowerBound() )
1635 || ( Ki.upperBound() != K.upperBound() ) )
1636 trace.warning() << "[Shortcuts::makeIdxDigitalSurface]"
1637 << " Incompatible digital spaces for surface " << i << std::endl;
1638 surfels.insert( surfaces[ i ]->begin(), surfaces[ i ]->end() );
1639 }
1640 return makeIdxDigitalSurface( surfels, K, params );
1641 }
1642
1643
1657 template <typename TDigitalSurfaceContainer>
1658 static CellRange
1660 ( Cell2Index& c2i,
1662 const Dimension k )
1663 {
1664 CellRange result;
1665 // Approximate number of pointels given the number of 2-cells (valid for 2d surfaces in nD).
1666 result.reserve( 2 * surface->size() + 100 );
1667 const KSpace& K = refKSpace( surface );
1668 Idx n = 0;
1669 for ( auto&& surfel : *surface )
1670 {
1671 CellRange primal_cells = getPrimalCells( K, surfel, k );
1672 for ( auto&& primal_cell : primal_cells )
1673 {
1674 if ( ! c2i.count( primal_cell ) )
1675 {
1676 result.push_back( primal_cell );
1677 c2i[ primal_cell ] = n++;
1678 }
1679 }
1680 }
1681 return result;
1682 }
1683
1696 template <typename TDigitalSurfaceContainer>
1697 static PointelRange
1699 (
1701 const Dimension k )
1702 {
1703 Cell2Index c2i;
1704 return getCellRange( c2i, surface, k );
1705 }
1706
1727 template <typename TDigitalSurfaceContainer>
1728 static PointelRange
1730 ( Cell2Index& c2i,
1732 {
1733 PointelRange result;
1734 result.reserve( surface->size() );
1735 const KSpace& K = refKSpace( surface );
1736 Idx n = 0;
1737 for ( auto&& surfel : *surface )
1738 {
1739 CellRange primal_vtcs = getPointelRange( K, surfel );
1740 for ( auto&& primal_vtx : primal_vtcs )
1741 {
1742 if ( ! c2i.count( primal_vtx ) )
1743 {
1744 result.push_back( primal_vtx );
1745 c2i[ primal_vtx ] = n++;
1746 }
1747 }
1748 }
1749 return result;
1750 }
1751
1768 template <typename TDigitalSurfaceContainer>
1769 static PointelRange
1776
1785 static PointelRange
1787 ( const KSpace& K, const SCell& surfel )
1788 {
1789 return KSpace::dimension == 3
1790 ? getPrimalVertices( K, surfel, true )
1791 : getPrimalVertices( K, surfel );
1792 }
1793
1805 template <typename TDigitalSurfaceContainer>
1806 static SurfelRange
1809 const Parameters& params = parametersDigitalSurface() )
1810 {
1811 return getSurfelRange( surface, *( surface->begin() ), params );
1812 }
1813
1828 template <typename TDigitalSurfaceContainer>
1829 static SurfelRange
1832 const Surfel& start_surfel,
1833 const Parameters& params = parametersDigitalSurface() )
1834 {
1835 typedef ::DGtal::DigitalSurface<TDigitalSurfaceContainer> AnyDigitalSurface;
1836 SurfelRange result;
1837 std::string traversal = params[ "surfaceTraversal" ].as<std::string>();
1838 if ( traversal == "DepthFirst" )
1839 {
1841 typedef GraphVisitorRange< Visitor > VisitorRange;
1842 VisitorRange range( new Visitor( *surface, start_surfel ) );
1843 std::for_each( range.begin(), range.end(),
1844 [&result] ( Surfel s ) { result.push_back( s ); } );
1845 }
1846 else if ( traversal == "BreadthFirst" )
1847 {
1849 typedef GraphVisitorRange< Visitor > VisitorRange;
1850 VisitorRange range( new Visitor( *surface, start_surfel ) );
1851 std::for_each( range.begin(), range.end(),
1852 [&result] ( Surfel s ) { result.push_back( s ); } );
1853 }
1854 else
1855 {
1856 std::for_each( surface->begin(), surface->end(),
1857 [&result] ( Surfel s ) { result.push_back( s ); } );
1858 }
1859 return result;
1860 }
1861
1871 static IdxSurfelRange
1874 const Parameters& params = parametersDigitalSurface() )
1875 {
1876 return getIdxSurfelRange( surface, (IdxSurfel) 0, params );
1877 }
1878
1891 static IdxSurfelRange
1894 const IdxSurfel& start_surfel,
1895 const Parameters& params = parametersDigitalSurface() )
1896 {
1897 IdxSurfelRange result;
1898 std::string traversal = params[ "surfaceTraversal" ].as<std::string>();
1899 if ( traversal == "DepthFirst" )
1900 {
1902 typedef GraphVisitorRange< Visitor > VisitorRange;
1903 VisitorRange range( new Visitor( *surface, start_surfel ) );
1904 std::for_each( range.begin(), range.end(),
1905 [&result] ( IdxSurfel s ) { result.push_back( s ); } );
1906 }
1907 else if ( traversal == "BreadthFirst" )
1908 {
1910 typedef GraphVisitorRange< Visitor > VisitorRange;
1911 VisitorRange range( new Visitor( *surface, start_surfel ) );
1912 std::for_each( range.begin(), range.end(),
1913 [&result] ( IdxSurfel s ) { result.push_back( s ); } );
1914 }
1915 else return surface->allVertices();
1916 return result;
1917 }
1930 template <typename TDigitalSurfaceContainer,
1931 typename TCellEmbedder>
1932 static bool
1935 const TCellEmbedder& embedder,
1936 std::string off_file,
1937 const Color& face_color=DGtal::Color::None)
1938
1939 {
1940 BOOST_STATIC_ASSERT (( KSpace::dimension == 3 ));
1941
1942 std::ofstream output_off( off_file.c_str() );
1943 output_off << "OFF" << std::endl;
1944 output_off << "# Generated from DGtal::Shortcuts from the DGTal library" << std::endl;
1945 Cell2Index c2i;
1946 auto pointels = getPointelRange( c2i, digsurf );
1947 output_off << pointels.size() << " " << digsurf->size() << " " << 0 << " " << std::endl;
1948
1949
1950 // Number and output vertices.
1951 const KSpace& K = refKSpace( digsurf );
1952 for ( auto&& pointel : pointels )
1953 {
1954 RealPoint p = embedder( pointel );
1955 output_off << p[ 0 ] << " " << p[ 1 ] << " " << p[ 2 ] << std::endl;
1956 }
1957
1958 // Taking care of faces
1959 for ( auto&& surfel : *digsurf )
1960 {
1961 auto primal_vtcs = getPointelRange( K, surfel );
1962 output_off << primal_vtcs.size();
1963 {
1964 for ( auto&& primal_vtx : primal_vtcs )
1965 output_off << " " << (c2i[ primal_vtx ]);
1966 }
1967 if(face_color != DGtal::Color::None)
1968 {
1969 output_off << " ";
1970 output_off << face_color.r() << " " << face_color.g()
1971 << " " << face_color.b() << " " << face_color.a();
1972 }
1973 output_off << std::endl;
1974 }
1975 return output_off.good();
1976 }
1977
1978
1996 template <typename TDigitalSurfaceContainer,
1997 typename TCellEmbedder>
1998 static bool
2001 const TCellEmbedder& embedder,
2002 const RealVectors& normals,
2003 const Colors& diffuse_colors,
2004 std::string objfile,
2005 const Color& ambient_color = Color( 32, 32, 32 ),
2006 const Color& diffuse_color = Color( 200, 200, 255 ),
2007 const Color& specular_color = Color::White )
2008 {
2009 BOOST_STATIC_ASSERT (( KSpace::dimension == 3 ));
2010 std::string mtlfile;
2011 auto lastindex = objfile.find_last_of(".");
2012 if ( lastindex == std::string::npos )
2013 {
2014 mtlfile = objfile + ".mtl";
2015 objfile = objfile + ".obj";
2016 }
2017 else
2018 {
2019 mtlfile = objfile.substr(0, lastindex) + ".mtl";
2020 }
2021
2022 std::ofstream output_obj( objfile.c_str() );
2023 output_obj << "# OBJ format" << std::endl;
2024 output_obj << "# DGtal::MeshHelpers::exportOBJwithFaceNormalAndColor" << std::endl;
2025 output_obj << "o anObject" << std::endl;
2026 //remove directory to write material
2027 auto indexpath = objfile.find_last_of("/");
2028 output_obj << "mtllib " << mtlfile.substr(indexpath+1) << std::endl;
2029 std::ofstream output_mtl( mtlfile.c_str() );
2030 output_mtl << "# MTL format"<< std::endl;
2031 output_mtl << "# generated from MeshWriter from the DGTal library"<< std::endl;
2032 // Number and output vertices.
2033 const KSpace& K = refKSpace( digsurf );
2034 Cell2Index c2i;
2035 auto pointels = getPointelRange( c2i, digsurf );
2036 for ( auto&& pointel : pointels )
2037 {
2038 RealPoint p = embedder( pointel );
2039 output_obj << "v " << p[ 0 ] << " " << p[ 1 ] << " " << p[ 2 ] << std::endl;
2040 }
2041 // Taking care of normals
2042 Idx nbfaces = digsurf->size();
2043 bool has_normals = ( nbfaces == normals.size() );
2044 if ( has_normals )
2045 {
2046 for ( Idx f = 0; f < nbfaces; ++f )
2047 {
2048 const auto& p = normals[ f ];
2049 output_obj << "vn " << p[ 0 ] << " " << p[ 1 ] << " " << p[ 2 ] << std::endl;
2050 }
2051 }
2052 // Taking care of materials
2053 bool has_material = ( nbfaces == diffuse_colors.size() );
2054 Idx idxMaterial = 0;
2055 std::map<Color, Idx > mapMaterial;
2056 if ( has_material )
2057 {
2058 for ( Idx f = 0; f < nbfaces; ++f )
2059 {
2060 Color c = diffuse_colors[ f ];
2061 if ( mapMaterial.count( c ) == 0 )
2062 {
2064 ( output_mtl, idxMaterial, ambient_color, c, specular_color );
2065 mapMaterial[ c ] = idxMaterial++;
2066 }
2067 }
2068 }
2069 else
2070 {
2072 ( output_mtl, idxMaterial, ambient_color, diffuse_color, specular_color );
2073 }
2074
2075 // Taking care of faces
2076 Idx f = 0;
2077 for ( auto&& surfel : *digsurf )
2078 {
2079 output_obj << "usemtl material_"
2080 << ( has_material ? mapMaterial[ diffuse_colors[ f ] ] : idxMaterial )
2081 << std::endl;
2082 output_obj << "f";
2083 auto primal_vtcs = getPointelRange( K, surfel );
2084 // The +1 in lines below is because indexing starts at 1 in OBJ file format.
2085 if ( has_normals )
2086 {
2087 for ( auto&& primal_vtx : primal_vtcs )
2088 output_obj << " " << (c2i[ primal_vtx ]+1) << "//" << (f+1);
2089 }
2090 else
2091 {
2092 for ( auto&& primal_vtx : primal_vtcs )
2093 output_obj << " " << (c2i[ primal_vtx ]+1);
2094 }
2095 output_obj << std::endl;
2096 f += 1;
2097 }
2098 output_mtl.close();
2099 return output_obj.good();
2100 }
2101
2117 template <typename TDigitalSurfaceContainer>
2118 static bool
2121 const RealVectors& normals,
2122 const Colors& diffuse_colors,
2123 std::string objfile,
2124 const Color& ambient_color = Color( 32, 32, 32 ),
2125 const Color& diffuse_color = Color( 200, 200, 255 ),
2126 const Color& specular_color = Color::White )
2127 {
2128 auto embedder = getCellEmbedder( digsurf );
2129 return saveOBJ( digsurf, embedder, normals, diffuse_colors, objfile,
2130 ambient_color, diffuse_color, specular_color );
2131 }
2132
2146 template <typename TDigitalSurfaceContainer>
2147 static bool
2150 std::string off_file,
2151 const Color& face_color = Color( 32, 32, 32 ))
2152 {
2153 auto embedder = getCellEmbedder( digsurf );
2154 return saveOFF( digsurf, embedder, off_file, face_color);
2155 }
2168 template <typename TDigitalSurfaceContainer>
2169 static bool
2172 std::string objfile,
2173 const Color& ambient_color = Color( 32, 32, 32 ),
2174 const Color& diffuse_color = Color( 200, 200, 255 ),
2175 const Color& specular_color = Color::White )
2176 {
2177 auto embedder = getCellEmbedder( digsurf );
2178 return saveOBJ( digsurf, embedder, RealVectors(), Colors(), objfile,
2179 ambient_color, diffuse_color, specular_color );
2180 }
2181
2182
2198 static bool
2200 ( const RealPoints& positions,
2201 const RealVectors& vf,
2202 double thickness,
2203 const Colors& diffuse_colors,
2204 std::string objfile,
2205 const Color& ambient_color = Color( 32, 32, 32 ),
2206 const Color& diffuse_color = Color( 200, 200, 255 ),
2207 const Color& specular_color = Color::White )
2208 {
2209 BOOST_STATIC_ASSERT (( KSpace::dimension == 3 ));
2210 std::string mtlfile;
2211 auto lastindex = objfile.find_last_of(".");
2212 if ( lastindex == std::string::npos )
2213 {
2214 mtlfile = objfile + ".mtl";
2215 objfile = objfile + ".obj";
2216 }
2217 else
2218 {
2219 mtlfile = objfile.substr(0, lastindex) + ".mtl";
2220 }
2221 std::ofstream output_obj( objfile.c_str() );
2222 output_obj << "# OBJ format" << std::endl;
2223 output_obj << "# DGtal::saveOBJ" << std::endl;
2224 output_obj << "o vectors" << std::endl;
2225 output_obj << "mtllib " << mtlfile << std::endl;
2226 std::ofstream output_mtl( mtlfile.c_str() );
2227 output_mtl << "# MTL format"<< std::endl;
2228 output_mtl << "# generated from MeshWriter from the DGTal library"<< std::endl;
2229 // Output vertices
2230 auto n = std::min( positions.size(), vf.size() );
2231 for ( unsigned int i = 0; i < n; ++i )
2232 {
2233 RealPoint p0 = positions[ i ];
2234 RealPoint p1 = p0 + vf[ i ];
2235 RealVector v = vf[ i ];
2236 RealVector absv = RealVector( fabs( v[ 0 ] ), fabs( v[ 1 ] ), fabs( v[ 2 ] ) );
2237 auto mc = std::max_element( absv.begin(), absv.end() ) - absv.begin();
2238 RealVector b =
2239 mc == 2 ? RealVector( 1, 0, 0 ) :
2240 mc == 1 ? RealVector( 0, 0, 1 ) : RealVector( 0, 1, 0 );
2241 RealVector e0 = v.crossProduct( b ).getNormalized();
2242 RealVector e1 = v.crossProduct( e0 ).getNormalized();
2243 RealPoint t[4] = { thickness * e0, thickness * e1,
2244 -thickness * e0, -thickness * e1 };
2245 for ( unsigned int j = 0; j < 4; ++j ) {
2246 RealPoint pt0 = p0 + t[ j ];
2247 RealPoint pt1 = p1 + t[ j ];
2248 output_obj << "v " << pt0[ 0 ] << " " << pt0[ 1 ] << " " << pt0[ 2 ]
2249 << std::endl;
2250 output_obj << "v " << pt1[ 0 ] << " " << pt1[ 1 ] << " " << pt1[ 2 ]
2251 << std::endl;
2252 }
2253 }
2254 // Simplify materials (very useful for blender).
2255 std::map<Color,Idx> map_colors;
2256 {
2257 Idx j = 0;
2258 for ( auto && c : diffuse_colors )
2259 if ( ! map_colors.count( c ) )
2260 map_colors[ c ] = j++;
2261 }
2262
2263 // Output materials
2264 bool has_material = ! diffuse_colors.empty();
2265 if ( has_material )
2266 for ( auto&& pair : map_colors )
2268 ( output_mtl, pair.second, ambient_color, pair.first, specular_color);
2269 else
2271 ( output_mtl, 0, ambient_color, diffuse_color, specular_color );
2272 // Output faces
2273 for ( Idx i = 0; i < n; ++i )
2274 {
2275 output_obj << "usemtl material_" // << ( has_material ? i : 0 )
2276 << ( has_material ? map_colors[ diffuse_colors[ i ] ] : 0 )
2277 << std::endl;
2278 Idx b = 8*i+1;
2279 for ( Idx j = 0; j < 8; j += 2 )
2280 output_obj << "f " << (b+j) << " " << (b+j+1)
2281 << " " << (b+(j+3)%8) << " " << (b+(j+2)%8) << std::endl;
2282 output_obj << "f " << b << " " << (b+2)
2283 << " " << (b+4) << " " << (b+6) << std::endl;
2284 output_obj << "f " << (b+1) << " " << (b+7)
2285 << " " << (b+5) << " " << (b+3) << std::endl;
2286 }
2287 output_mtl.close();
2288 return output_obj.good();
2289 }
2290
2291 // ----------------------- Mesh services ------------------------------
2292 public:
2293
2298 {
2299 return Parameters
2300 ( "faceSubdivision", "Centroid" );
2301 }
2302
2316 {
2317 auto pTriSurf = CountedPtr<TriangulatedSurface>
2318 ( new TriangulatedSurface ); // acquired
2319 bool ok = MeshHelpers::mesh2TriangulatedSurface( *aMesh, *pTriSurf );
2320 return ok ? pTriSurf : CountedPtr< TriangulatedSurface >( nullptr );
2321 }
2322
2331 static CountedPtr< Mesh >
2333 const Color& aColor = Color::White )
2334 {
2335 auto pMesh = CountedPtr<Mesh>( new Mesh( aColor ) ); // acquired
2336 MeshHelpers::triangulatedSurface2Mesh( *triSurf, *pMesh );
2337 return pMesh;
2338 }
2339
2348 static CountedPtr< Mesh >
2350 const Color& aColor = Color::White )
2351 {
2352 auto pMesh = CountedPtr<Mesh>( new Mesh( aColor ) ); // acquired
2353 MeshHelpers::polygonalSurface2Mesh( *polySurf, *pMesh );
2354 return pMesh;
2355 }
2356
2363 template < typename TContainer >
2367 {
2368 auto embedder = getCellEmbedder( aSurface );
2369 auto pTriSurf = CountedPtr<TriangulatedSurface>
2370 ( new TriangulatedSurface ); // acquired
2372 ( *aSurface, embedder, *pTriSurf, s2i );
2373 return pTriSurf;
2374 }
2375
2381 template < typename TContainer >
2384 {
2385 Surfel2Index s2i;
2386 return makeTriangulatedSurface( s2i, aSurface );
2387 }
2388
2408 const Parameters& params = parametersMesh() )
2409 {
2410 std::string faceSubdivision = params[ "faceSubdivision" ].as<std::string>();
2411 bool centroid = ( faceSubdivision == "Centroid" );
2412 auto pTriSurf = CountedPtr<TriangulatedSurface>
2413 ( new TriangulatedSurface ); // acquired
2414 MeshHelpers::polygonalSurface2TriangulatedSurface( *polySurf, *pTriSurf, centroid );
2415 return pTriSurf;
2416 }
2417
2428 {
2429 auto pPolySurf = CountedPtr<PolygonalSurface>
2430 ( new PolygonalSurface ); // acquired
2431 bool ok = MeshHelpers::mesh2PolygonalSurface( *aMesh, *pPolySurf );
2432 return ok ? pPolySurf : CountedPtr< PolygonalSurface >( nullptr );
2433 }
2434
2450 const Parameters& params =
2454 {
2455 auto K = getKSpace( gray_scale_image );
2456 auto bimage = makeBinaryImage( gray_scale_image, params );
2457 auto digSurf = makeDigitalSurface( bimage, K, params );
2458 RealVector gh = { params[ "gridsizex" ].as<double>(),
2459 params[ "gridsizey" ].as<double>(),
2460 params[ "gridsizez" ].as<double>() };
2461 double threshold = params[ "thresholdMin" ].as<double>() + 0.5;
2462 typedef RegularPointEmbedder<Space> PointEmbedder;
2464 < KSpace, GrayScaleImage, PointEmbedder > ImageCellEmbedder;
2465 PointEmbedder pembedder;
2466 pembedder.init( gh );
2467 ImageCellEmbedder cembedder;
2468 cembedder.init( K, *gray_scale_image, pembedder, threshold );
2469 auto pPolySurf = CountedPtr<PolygonalSurface>
2470 ( new PolygonalSurface ); // acquired
2471 Surfel2Index s2i;
2473 ( *digSurf, cembedder, *pPolySurf, s2i );
2474 return pPolySurf;
2475 }
2476
2493 const Parameters& params =
2497 {
2498 auto K = getKSpace( gray_scale_image );
2499 auto bimage = makeBinaryImage( gray_scale_image, params );
2500 auto digSurf = makeDigitalSurface( bimage, K, params );
2501 RealVector gh = { params[ "gridsizex" ].as<double>(),
2502 params[ "gridsizey" ].as<double>(),
2503 params[ "gridsizez" ].as<double>() };
2504 double threshold = params[ "thresholdMin" ].as<double>() + 0.5;
2505 typedef RegularPointEmbedder<Space> PointEmbedder;
2507 < KSpace, GrayScaleImage, PointEmbedder > ImageCellEmbedder;
2508 PointEmbedder pembedder;
2509 pembedder.init( gh );
2510 ImageCellEmbedder cembedder;
2511 cembedder.init( K, *gray_scale_image, pembedder, threshold );
2512 auto pPolySurf = CountedPtr<TriangulatedSurface>
2513 ( new TriangulatedSurface ); // acquired
2514 Surfel2Index s2i;
2516 ( *digSurf, cembedder, *pPolySurf, s2i );
2517 return pPolySurf;
2518 }
2519
2527 template < typename TContainer >
2531 {
2532 BOOST_STATIC_ASSERT (( KSpace::dimension == 3 ));
2533 auto embedder = getCellEmbedder( aSurface );
2534 auto pPolySurf = CountedPtr<PolygonalSurface>
2535 ( new PolygonalSurface ); // acquired
2537 ( *aSurface, embedder, *pPolySurf, s2i );
2538 return pPolySurf;
2539 }
2540
2547 template < typename TContainer >
2550 {
2551 Surfel2Index s2i;
2552 return makeDualPolygonalSurface( s2i, aSurface );
2553 }
2554
2561 template < typename TContainer >
2565 {
2566 BOOST_STATIC_ASSERT (( KSpace::dimension == 3 ));
2567 auto pPolySurf = CountedPtr<PolygonalSurface>
2568 ( new PolygonalSurface( aSurface->heds(),
2569 aSurface->positions().storage() ) );
2570 return pPolySurf;
2571 }
2572
2580 template < typename TContainer >
2584 {
2585 BOOST_STATIC_ASSERT (( KSpace::dimension == 3 ));
2586 auto embedder = getCellEmbedder( aSurface );
2587 auto pPolySurf = CountedPtr<PolygonalSurface>
2588 ( new PolygonalSurface ); // acquired
2590 ( *aSurface, embedder, *pPolySurf, c2i );
2591 return ok ? pPolySurf : CountedPtr< PolygonalSurface >( nullptr );
2592 }
2593
2600 template < typename TContainer >
2603 {
2604 Cell2Index c2i;
2605 return makePrimalPolygonalSurface( c2i, aSurface );
2606 }
2607
2614 template < typename TContainer >
2618 {
2619 auto dsurf = makeDigitalSurface( aSurface );
2620 Cell2Index c2i;
2621 return makePrimalPolygonalSurface( c2i, dsurf );
2622 }
2623
2631 template < typename TContainer >
2635 {
2636 BOOST_STATIC_ASSERT (( KSpace::dimension == 3 ));
2637 auto embedder = getCellEmbedder( aSurface );
2638 auto pPolySurf = CountedPtr<SurfaceMesh>( new SurfaceMesh ); // acquired
2639 bool ok = MeshHelpers::digitalSurface2PrimalSurfaceMesh( *aSurface, embedder, *pPolySurf, c2i );
2640 return ok ? pPolySurf : CountedPtr< SurfaceMesh >( nullptr );
2641 }
2642
2649 template < typename TContainer >
2652 {
2653 Cell2Index c2i;
2654 return makePrimalSurfaceMesh( c2i, aSurface );
2655 }
2656
2663 template < typename TContainer >
2666 {
2667 auto dsurf = makeDigitalSurface( aSurface );
2668 Cell2Index c2i;
2669 return makePrimalSurfaceMesh( c2i, dsurf );
2670 }
2671
2677 makeSurfaceMesh(const std::string& path)
2678 {
2679 std::ifstream file(path);
2680 if (file.is_open())
2681 {
2682 auto surf = CountedPtr<SurfaceMesh>( new SurfaceMesh );
2684
2685 return ok ? surf : CountedPtr<SurfaceMesh>( nullptr );
2686 }
2687
2688 return CountedPtr<SurfaceMesh>( nullptr );
2689 }
2690
2691
2699 template <typename TPoint, typename TVector>
2700 static bool
2703 const std::string& objfile )
2704 {
2705 std::ofstream output( objfile.c_str() );
2706 bool ok = MeshHelpers::exportOBJ( output, *surf );
2707 output.close();
2708 return ok;
2709 }
2710
2717 template <typename TPoint>
2718 static bool
2721 const std::string& objfile )
2722 {
2723 std::ofstream output( objfile.c_str() );
2724 bool ok = MeshHelpers::exportOBJ( output, *polysurf );
2725 output.close();
2726 return ok;
2727 }
2728
2737 template <typename TPoint>
2738 static bool
2740 std::string off_file,
2741 const Color& face_color = DGtal::Color::None)
2742
2743 {
2746 std::ofstream output( off_file.c_str() );
2747 for (unsigned int i=0; i< m.nbFaces(); i++)
2748 {
2749 m.setFaceColor(i, face_color);
2750 }
2751 bool ok = MeshWriter< TPoint >::export2OFF( output, m, true );
2752 output.close();
2753 return ok;
2754 }
2755
2762 template <typename TPoint>
2763 static bool
2766 const std::string& objfile )
2767 {
2768 std::ofstream output( objfile.c_str() );
2769 bool ok = MeshHelpers::exportOBJ( output, *trisurf );
2770 output.close();
2771 return ok;
2772 }
2773
2786 template <typename TPoint>
2787 static bool
2790 const RealVectors& normals,
2791 const Colors& diffuse_colors,
2792 std::string objfile,
2793 const Color& ambient_color = Color( 32, 32, 32 ),
2794 const Color& diffuse_color = Color( 200, 200, 255 ),
2795 const Color& specular_color = Color::White )
2796 {
2797 std::string mtlfile;
2798 auto lastindex = objfile.find_last_of(".");
2799 if ( lastindex == std::string::npos )
2800 {
2801 mtlfile = objfile + ".mtl";
2802 objfile = objfile + ".obj";
2803 }
2804 else
2805 {
2806 mtlfile = objfile.substr(0, lastindex) + ".mtl";
2807 }
2808 std::ofstream output( objfile.c_str() );
2810 ( output, mtlfile, *polysurf, normals, diffuse_colors,
2811 ambient_color, diffuse_color, specular_color );
2812 output.close();
2813 return ok;
2814 }
2815
2828 template <typename TPoint>
2829 static bool
2832 const RealVectors& normals,
2833 const Colors& diffuse_colors,
2834 std::string objfile,
2835 const Color& ambient_color = Color( 32, 32, 32 ),
2836 const Color& diffuse_color = Color( 200, 200, 255 ),
2837 const Color& specular_color = Color::White )
2838 {
2839 std::string mtlfile;
2840 auto lastindex = objfile.find_last_of(".");
2841 if ( lastindex == std::string::npos )
2842 {
2843 mtlfile = objfile + ".mtl";
2844 objfile = objfile + ".obj";
2845 }
2846 else
2847 {
2848 mtlfile = objfile.substr(0, lastindex) + ".mtl";
2849 }
2850 std::ofstream output( objfile.c_str() );
2852 ( output, mtlfile, *trisurf, normals, diffuse_colors,
2853 ambient_color, diffuse_color, specular_color );
2854 output.close();
2855 return ok;
2856 }
2857
2871 template <typename TPoint, typename TVector>
2872 static bool
2875 const RealVectors& normals,
2876 const Colors& diffuse_colors,
2877 std::string objfile,
2878 const Color& ambient_color = Color( 32, 32, 32 ),
2879 const Color& diffuse_color = Color( 200, 200, 255 ),
2880 const Color& specular_color = Color::White )
2881 {
2882 std::string mtlfile;
2883 auto lastindex = objfile.find_last_of(".");
2884 if ( lastindex == std::string::npos )
2885 {
2886 mtlfile = objfile + ".mtl";
2887 objfile = objfile + ".obj";
2888 }
2889 else
2890 {
2891 mtlfile = objfile.substr(0, lastindex) + ".mtl";
2892 }
2893 std::ofstream output( objfile.c_str() );
2895 ( output, mtlfile, *surf, normals, diffuse_colors,
2896 ambient_color, diffuse_color, specular_color );
2897 output.close();
2898 return ok;
2899 }
2900
2909 template <typename TPoint>
2910 static bool
2912 std::string off_file,
2913 const Color& face_color = DGtal::Color::None)
2914
2915 {
2918 std::ofstream output( off_file.c_str() );
2919 for (unsigned int i=0; i< m.nbFaces(); i++)
2920 {
2921 m.setFaceColor(i, face_color);
2922 }
2923 bool ok = MeshWriter< TPoint >::export2OFF( output, m, true );
2924 output.close();
2925 return ok;
2926 }
2927
2928
2929 // ------------------------------ utilities ------------------------------
2930 public:
2931
2937 {
2938 return Parameters
2939 ( "colormap", "Custom" )
2940 ( "zero-tic", 0.0 );
2941 }
2942
2959 template <typename TValue>
2960 static IdxRange
2961 getRangeMatch( const std::vector< TValue >& s1, const std::vector< TValue >& s2,
2962 bool perfect = false )
2963 {
2964 if ( perfect && ( s1.size() != s2.size() ) ) return IdxRange();
2965 std::map<TValue, Idx> M;
2966 Idx idx = 0;
2967 for ( auto val : s2 ) M[ val ] = idx++;
2968 IdxRange V( s1.size() );
2969 idx = 0;
2970 for ( auto val : s1 )
2971 {
2972 auto it = M.find( val );
2973 if ( it != M.end() ) V[ idx++ ] = it->second;
2974 else
2975 {
2976 if ( perfect ) return IdxRange();
2977 V[ idx++ ] = s2.size();
2978 }
2979 }
2980 return V;
2981 }
2982
2994 template <typename TValue>
2995 static std::vector< TValue >
2996 getMatchedRange( const std::vector< TValue >& range, const IdxRange& match )
2997 {
2998 std::vector< TValue > result( match.size() );
2999 for ( Idx i = 0; i < result.size(); i++ )
3000 result[ i ] = range[ match[ i ] ];
3001 return result;
3002 }
3003
3004
3010 static ColorMap
3012 Scalar max,
3013 const Parameters& params = parametersUtilities() )
3014 {
3015 std::string cmap = params[ "colormap" ].as<std::string>();
3016 if ( cmap == "Cool" ) return ColorMap( min, max, CMAP_COOL );
3017 else if ( cmap == "Copper" ) return ColorMap( min, max, CMAP_COPPER );
3018 else if ( cmap == "Hot" ) return ColorMap( min, max, CMAP_HOT );
3019 else if ( cmap == "Jet" ) return ColorMap( min, max, CMAP_JET );
3020 else if ( cmap == "Spring" ) return ColorMap( min, max, CMAP_SPRING );
3021 else if ( cmap == "Summer" ) return ColorMap( min, max, CMAP_SUMMER );
3022 else if ( cmap == "Autumn" ) return ColorMap( min, max, CMAP_AUTUMN );
3023 else if ( cmap == "Winter" ) return ColorMap( min, max, CMAP_WINTER );
3024 else if ( cmap == "Error" )
3025 {
3026 ColorMap gradcmap( min, max );
3027 gradcmap.addColor( Color( 255, 255, 255 ) );
3028 gradcmap.addColor( Color( 255, 0, 0 ) );
3029 gradcmap.addColor( Color( 0, 0, 0 ) );
3030 return gradcmap;
3031 }
3032 // Custom colormap
3033 ColorMap gradcmap( min, max );
3034 gradcmap.addColor( Color( 0, 0, 255 ) );
3035 gradcmap.addColor( Color( 0, 255, 255 ) );
3036 gradcmap.addColor( Color( 255, 255, 255 ) );
3037 gradcmap.addColor( Color( 255, 255, 0 ) );
3038 gradcmap.addColor( Color( 255, 0, 0 ) );
3039 return gradcmap;
3040 }
3041
3048 static ZeroTickedColorMap
3050 Scalar max,
3051 const Parameters& params = parametersUtilities() )
3052 {
3053 auto cmap = getColorMap( min, max, params );
3054 auto ztic = params[ "zero-tic" ].as<double>();
3055 ZeroTickedColorMap ztic_cmap( cmap, Color::Black );
3056 if ( ztic <= 0.0 ) return ztic_cmap;
3057 if ( min <= 0.0 && 0.0 <= max )
3058 ztic_cmap.addTick( 0.0, ztic );
3059 ztic_cmap.finalize();
3060 return ztic_cmap;
3061 }
3062
3063
3072 template <typename TCellEmbedder = CanonicCellEmbedder< KSpace > >
3073 static bool
3075 ( std::ostream& output,
3076 const SurfelRange& surfels,
3077 const TCellEmbedder& embedder )
3078 {
3079 typedef unsigned long Size;
3080 BOOST_STATIC_ASSERT (( KSpace::dimension == 3 ));
3082 const KSpace& K = embedder.space();
3083 // Number and output vertices.
3084 std::map< Cell, Size > vtx_numbering;
3085 Size n = 1; // OBJ vertex numbering start at 1
3086 for ( auto&& s : surfels )
3087 {
3088 auto primal_vtcs = getPointelRange( K, s, true );
3089 for ( auto&& primal_vtx : primal_vtcs )
3090 {
3091 if ( ! vtx_numbering.count( primal_vtx ) )
3092 {
3093 vtx_numbering[ primal_vtx ] = n++;
3094 // Output vertex positions
3095 RealPoint p = embedder( primal_vtx );
3096 output << "v " << p[ 0 ] << " " << p[ 1 ] << " " << p[ 2 ] << std::endl;
3097 }
3098 }
3099 }
3100 // Outputs all faces
3101 for ( auto&& s : surfels )
3102 {
3103 output << "f";
3104 auto primal_vtcs = getPointelRange( K, s, true );
3105 for ( auto&& primal_vtx : primal_vtcs )
3106 output << " " << vtx_numbering[ primal_vtx ];
3107 output << std::endl;
3108 }
3109 return output.good();
3110 }
3111
3123 template <typename TAnyDigitalSurface>
3124 static bool
3126 ( std::ostream& output,
3128 {
3129 auto embedder = getCellEmbedder( surface );
3130 return outputPrimalDigitalSurfaceAsObj( output, surface, embedder );
3131 }
3132
3150 template < typename TAnyDigitalSurface,
3151 typename TCellEmbedder = CanonicCellEmbedder< KSpace > >
3152 static bool
3154 ( std::ostream& output,
3156 const TCellEmbedder& embedder )
3157 {
3158 auto surfels = getSurfelRange( surface, Parameters( "Traversal", "Default" ) );
3159 return outputSurfelsAsObj( output, surfels, embedder );
3160 }
3161
3170 static bool
3172 ( std::ostream& output,
3174 {
3175 auto embedder = getCellEmbedder( surface );
3176 return outputPrimalIdxDigitalSurfaceAsObj( output, surface, embedder );
3177 }
3178
3192 template <typename TCellEmbedder = CanonicCellEmbedder< KSpace > >
3193 static bool
3195 ( std::ostream& output,
3197 const TCellEmbedder& embedder )
3198 {
3199 auto idxsurfels = getIdxSurfelRange( surface, Parameters( "Traversal", "Default" ) );
3200 auto surfelmap = surface->surfels();
3201 SurfelRange surfels;
3202 for ( auto&& idx : idxsurfels )
3203 surfels.push_back( surfelmap[ idx ] );
3204 return outputSurfelsAsObj( output, surfels, embedder );
3205 }
3206
3223 template <typename TDigitalSurfaceContainer>
3224 static bool
3226 ( std::ostream& output,
3228 const Parameters& params = parametersMesh() )
3229 {
3230 auto embedder = getCellEmbedder( surface );
3231 return outputDualDigitalSurfaceAsObj( output, surface, embedder, params );
3232 }
3233
3256 template < typename TDigitalSurfaceContainer,
3257 typename TCellEmbedder = CanonicCellEmbedder< KSpace > >
3258 static bool
3260 ( std::ostream& output,
3262 const TCellEmbedder& embedder,
3263 const Parameters& params = parametersMesh() )
3264 {
3265 typedef unsigned long Size;
3266 BOOST_STATIC_ASSERT (( KSpace::dimension == 3 ));
3268 std::string dualFaceSubdivision = params[ "faceSubdivision" ].as<std::string>();
3269 const int subdivide
3270 = dualFaceSubdivision == "Naive" ? 1
3271 : dualFaceSubdivision == "Centroid" ? 2
3272 : 0;
3273 const KSpace& K = embedder.space();
3274 // Number and ouput vertices.
3275 std::map< Vertex, Size > vtx_numbering;
3276 std::map< Face, Size > sub_numbering;
3277 Size n = 1; // OBJ vertex numbering start at 1
3278 for ( auto && s : *surface )
3279 {
3280 if ( ! vtx_numbering.count( s ) )
3281 {
3282 vtx_numbering[ s ] = n++;
3283 // Output vertex positions
3284 RealPoint p = embedder( K.unsigns( s ) );
3285 output << "v " << p[ 0 ] << " " << p[ 1 ] << " " << p[ 2 ] << std::endl;
3286 }
3287 }
3288 auto faces = surface->allClosedFaces();
3289 // Prepare centroids if necessary
3290 if ( subdivide == 2 )
3291 {
3292 for ( auto&& f : faces )
3293 {
3294 auto vtcs = surface->verticesAroundFace( f );
3295 Size nv = vtcs.size();
3296 if ( nv > 3 )
3297 {
3298 sub_numbering[ f ] = n++;
3300 for ( auto&& s : vtcs ) p += embedder( K.unsigns( s ) );
3301 p /= nv;
3302 output << "v " << p[ 0 ] << " " << p[ 1 ] << " " << p[ 2 ] << std::endl;
3303 }
3304 }
3305 }
3306 // Outputs closed faces.
3307 if ( subdivide == 0 )
3308 { // No subdivision
3309 for ( auto&& f : faces )
3310 {
3311 output << "f";
3312 auto vtcs = surface->verticesAroundFace( f );
3313 std::reverse( vtcs.begin(), vtcs.end() );
3314 for ( auto&& s : vtcs )
3315 output << " " << vtx_numbering[ s ];
3316 output << std::endl;
3317 }
3318 }
3319 else if ( subdivide == 1 )
3320 { // naive subdivision
3321 for ( auto&& f : faces )
3322 {
3323 auto vtcs = surface->verticesAroundFace( f );
3324 Size nv = vtcs.size();
3325 for ( Size i = 1; i < nv - 1; ++i )
3326 output << "f " << vtx_numbering[ vtcs[ 0 ] ]
3327 << " " << vtx_numbering[ vtcs[ i+1 ] ]
3328 << " " << vtx_numbering[ vtcs[ i ] ] << std::endl;
3329 }
3330 }
3331 else if ( subdivide == 2 )
3332 { // centroid subdivision
3333 for ( auto&& f : faces )
3334 {
3335 auto vtcs = surface->verticesAroundFace( f );
3336 Size nv = vtcs.size();
3337 if ( nv == 3 )
3338 output << "f " << vtx_numbering[ vtcs[ 0 ] ]
3339 << " " << vtx_numbering[ vtcs[ 2 ] ]
3340 << " " << vtx_numbering[ vtcs[ 1 ] ] << std::endl;
3341 else {
3342 Size c = sub_numbering[ f ];
3343 for ( Size i = 0; i < nv; ++i )
3344 {
3345 output << "f " << c
3346 << " " << vtx_numbering[ vtcs[ (i+1)%nv ] ]
3347 << " " << vtx_numbering[ vtcs[ i ] ] << std::endl;
3348 }
3349 }
3350 }
3351 }
3352 return output.good();
3353 }
3354
3355
3356 // -------------------- map I/O services ------------------------------------------
3357 public:
3358 struct CellWriter {
3359 void operator()( std::ostream& output, const KSpace& K, const Cell & cell )
3360 {
3361 for ( Dimension d = 0; d < KSpace::dimension; ++d )
3362 output << " " << K.sKCoord( cell, d );
3363 }
3364 };
3365 struct CellReader {
3366 Cell operator()( std::istream& input, const KSpace& K )
3367 {
3368 Point kp;
3369 for ( Dimension d = 0; d < KSpace::dimension; ++d )
3370 input >> kp[ d ];
3371 return K.uCell( kp );
3372 }
3373 };
3375 void operator()( std::ostream& output, const KSpace& K, const SCell & scell )
3376 {
3377 CellWriter::operator()( output, K, K.unsigns( scell ) );
3378 output << " " << K.sSign( scell );
3379 }
3380 };
3382 SCell operator()( std::istream& input, const KSpace& K )
3383 {
3384 Point kp;
3385 typename KSpace::Sign s;
3386 for ( Dimension d = 0; d < KSpace::dimension; ++d )
3387 input >> kp[ d ];
3388 input >> s;
3389 return K.sCell( kp, s );
3390 }
3391 };
3392
3393 template <typename Value>
3395 void operator()( std::ostream& output, const Value& v )
3396 {
3397 output << " " << v;
3398 }
3399 void operator()( std::ostream& output, const std::vector<Value>& vv )
3400 {
3401 for ( auto&& v : vv ) output << " " << v;
3402 }
3403 };
3404
3405 template <typename Value>
3407 bool operator()( std::istream& input, Value& value )
3408 {
3409 std::string str;
3410 std::getline( input, str );
3411 // construct a stream from the string
3412 std::stringstream strstr(str);
3413 // use stream iterators to copy the stream to the vector as whitespace separated strings
3414 std::istream_iterator<std::string> it(strstr);
3415 std::istream_iterator<std::string> end;
3416 std::vector<std::string> results(it, end);
3417 std::stringstream sstr( results[ 0 ] );
3418 sstr >> value;
3419 return ( results.size() == 1 ) && input.good();
3420 }
3421
3422 bool operator()( std::istream& input, std::vector<Value>& values )
3423 {
3424 std::string str;
3425 std::getline( input, str );
3426 // construct a stream from the string
3427 std::stringstream strstr(str);
3428 // use stream iterators to copy the stream to the vector as whitespace separated strings
3429 std::istream_iterator<std::string> it(strstr);
3430 std::istream_iterator<std::string> end;
3431 std::vector<std::string> results(it, end);
3432 values.resize( results.size() );
3433 for ( unsigned int i = 0; i < results.size(); ++i ) {
3434 std::stringstream sstr( results[ i ] );
3435 sstr >> values[ i ];
3436 }
3437 return input.good();
3438 }
3439 };
3440
3441 // Outputs in \a output a map \a anyMap: SCell -> Value given the
3442 // appropriate value \a writer.
3443 //
3444 // @tparam TSCellMap any model of map SCell -> Value., e.g. std::map<SCell,double>
3445 // @tparam TValueWriter any model of value writer, e.g. ValueWriter<double>
3446 //
3447 // @param[out] output the output stream
3448 // @param[in] K the Khalimsky space where cells are defined.
3449 // @param[in] anyMap the map associated a value to signed cells.
3450 // @param[in] writer the writer that can write values on the ouput
3451 // stream, e.g. ValueWriter<double> to write double value or
3452 // vector<double> values.
3453 template <typename TSCellMap, typename TValueWriter>
3454 static
3456 ( std::ostream& output,
3457 const KSpace& K,
3458 const TSCellMap& anyMap,
3459 const TValueWriter& writer )
3460 {
3461 SCellWriter w;
3462 for ( auto&& v : anyMap )
3463 {
3464 w( output, K, v.first );
3465 writer( output, v.second );
3466 output << std::endl;
3467 }
3468 return output.good();
3469 }
3470
3471 // Outputs in \a output a map \a anyMap: SCell -> value given the
3472 // appropriate value \a writer.
3473 //
3474 // @tparam TCellMap any model of map Cell -> Value., e.g. std::map<Cell,double>
3475 // @tparam TValueWriter any model of value writer, e.g. ValueWriter<double>
3476 //
3477 // @param[out] output the output stream
3478 // @param[in] K the Khalimsky space where cells are defined.
3479 // @param[in] anyMap the map associated a value to signed cells.
3480 // @param[in] writer the writer that can write values on the ouput
3481 // stream, e.g. ValueWriter<double> to write double value or
3482 // vector<double> values.
3483 template <typename TCellMap, typename TValueWriter>
3484 static
3486 ( std::ostream& output,
3487 const KSpace& K,
3488 const TCellMap& anyMap,
3489 const TValueWriter& writer )
3490 {
3491 CellWriter w;
3492 for ( auto&& v : anyMap )
3493 {
3494 w( output, K, v.first );
3495 writer( output, v.second );
3496 output << std::endl;
3497 }
3498 return output.good();
3499 }
3500
3506 static
3507 CellRange getPrimalCells( const KSpace& K, const SCell& s, const Dimension k )
3508 {
3509 auto faces = K.uFaces( K.unsigns( s ) );
3510 CellRange primal_cells;
3511 for ( auto&& f : faces )
3512 {
3513 if ( K.uDim( f ) == k ) primal_cells.push_back( f );
3514 }
3515 return primal_cells;
3516 }
3517
3522 static
3524 {
3525 return getPrimalCells( K, s, 0 );
3526 }
3527
3534 static
3535 CellRange getPrimalVertices( const KSpace& K, const Surfel& s, bool ccw )
3536 {
3537 BOOST_STATIC_ASSERT(( KSpace::dimension == 3 ));
3538 CellRange vtcs = getPrimalVertices( K, s );
3539 std::swap( vtcs[ 2 ], vtcs[ 3 ] );
3540 auto orth_dir = K.sOrthDir( s );
3541 auto direct = K.sDirect( s, orth_dir ) ? ccw : ! ccw;
3542 Vector s0s1 = K.uCoords( vtcs[ 1 ] ) - K.uCoords( vtcs[ 0 ] );
3543 Vector s0s2 = K.uCoords( vtcs[ 2 ] ) - K.uCoords( vtcs[ 0 ] );
3544 Vector t = s0s1.crossProduct( s0s2 );
3545 if ( ( ( t[ orth_dir ] > 0.0 ) && direct )
3546 || ( ( t[ orth_dir ] < 0.0 ) && ! direct ) )
3547 std::reverse( vtcs.begin(), vtcs.end() );
3548 return vtcs;
3549 }
3550
3551
3552 // ----------------------- Standard services ------------------------------
3553 public:
3554
3558 Shortcuts() = delete;
3559
3563 ~Shortcuts() = delete;
3564
3569 Shortcuts ( const Shortcuts & other ) = delete;
3570
3575 Shortcuts ( Shortcuts && other ) = delete;
3576
3582 Shortcuts & operator= ( const Shortcuts & other ) = delete;
3583
3589 Shortcuts & operator= ( Shortcuts && other ) = delete;
3590
3591 // ----------------------- Interface --------------------------------------
3592 public:
3593
3598 void selfDisplay ( std::ostream & out ) const
3599 {
3600 out << "[Shortcuts]";
3601 }
3602
3607 bool isValid() const
3608 {
3609 return true;
3610 }
3611
3612 // ------------------------- Protected Datas ------------------------------
3613 protected:
3614
3615 // ------------------------- Private Datas --------------------------------
3616 private:
3617
3618 // ------------------------- Hidden services ------------------------------
3619 protected:
3620
3621 // ------------------------- Internals ------------------------------------
3622 private:
3623
3624 }; // end of class Shortcuts
3625
3626
3633 template <typename T>
3634 std::ostream&
3635 operator<< ( std::ostream & out, const Shortcuts<T> & object );
3636
3637} // namespace DGtal
3638
3639
3641// Includes inline functions.
3642
3643// //
3645
3646#endif // !defined Shortcuts_h
3647
3648#undef Shortcuts_RECURSES
3649#endif // else defined(Shortcuts_RECURSES)
Aim: This class is useful to perform a breadth-first exploration of a graph given a starting point or...
Structure representing an RGB triple with alpha component.
Definition Color.h:77
static const Color None
Definition Color.h:421
static const Color Black
Definition Color.h:422
static const Color White
Definition Color.h:424
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition ConstAlias.h:187
Aim: Smart pointer based on reference counts.
Definition CountedPtr.h:80
Aim: This class is useful to perform a depth-first exploration of a graph given a starting point or s...
Aim: Represents a set of n-1-cells in a nD space, together with adjacency relation between these cell...
DigitalSurfaceContainer::Surfel Surfel
DigitalSurfaceContainer::Cell Cell
Surfel Vertex
Defines the type for a vertex.
std::vector< Arc > ArcRange
The range of arcs is defined as a vector.
DigitalSurfaceContainer::SCell SCell
Aim: A class for computing the Gauss digitization of some Euclidean shape, i.e. its intersection with...
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: Transforms a graph visitor into a single pass input range.
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
const ConstIterator & begin() const
const Point & lowerBound() const
const Point & upperBound() const
const ConstIterator & end() const
Aim: a cellular embedder for images. (default constructible, copy constructible, assignable)....
void init(ConstAlias< KSpace > K, ConstAlias< Image > f, ConstAlias< Embedder > e, double iso_value)
Aim: model of CEuclideanOrientedShape concepts to create a shape from a polynomial.
Aim: Represents a digital surface with the topology of its dual surface. Its aim is to mimick the sta...
HalfEdgeDataStructure::HalfEdgeIndex Arc
Aim: From a point predicate (model of concepts::CPointPredicate), this class constructs another point...
std::set< SCell > SurfelSet
Preferred type for defining a set of surfels (always signed cells).
static const constexpr Dimension dimension
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as the boundary of an impl...
Aim: This class converts a string polynomial expression in a multivariate polynomial.
Aim: Represents a multivariate polynomial, i.e. an element of , where K is some ring or field.
static bool exportOBJ(std::ostream &output, const TriangulatedSurface< Point > &trisurf)
static bool digitalSurface2PrimalSurfaceMesh(const DigitalSurface< DigitalSurfaceContainer > &dsurf, const CellEmbedder &cembedder, SurfaceMesh< typename CellEmbedder::Value, typename CellEmbedder::Value > &polysurf, CellMap &cellmap)
static bool digitalSurface2PrimalPolygonalSurface(const DigitalSurface< DigitalSurfaceContainer > &dsurf, const CellEmbedder &cembedder, PolygonalSurface< typename CellEmbedder::Value > &polysurf, CellMap &cellmap)
static bool mesh2TriangulatedSurface(const Mesh< Point > &mesh, TriangulatedSurface< Point > &trisurf)
static void polygonalSurface2TriangulatedSurface(const PolygonalSurface< Point > &polysurf, TriangulatedSurface< Point > &trisurf, bool centroid=true)
static bool exportMTLNewMaterial(std::ostream &output_mtl, unsigned long idxMaterial, const Color &ambient_color, const Color &diffuse_color, const Color &specular_color)
static void polygonalSurface2Mesh(const PolygonalSurface< Point > &polysurf, Mesh< Point > &mesh)
static bool exportOBJwithFaceNormalAndColor(std::ostream &output_obj, const std::string &mtl_filename, const SurfaceMesh &surf, const std::vector< typename SurfaceMesh::RealPoint > &normals, const std::vector< Color > &diffuse_colors, const Color &ambient_color=Color(32, 32, 32), const Color &diffuse_color=Color(200, 200, 255), const Color &specular_color=Color::White)
static void digitalSurface2DualTriangulatedSurface(const DigitalSurface< DigitalSurfaceContainer > &dsurf, const CellEmbedder &cembedder, TriangulatedSurface< typename CellEmbedder::Value > &trisurf, VertexMap &vertexmap)
static void digitalSurface2DualPolygonalSurface(const DigitalSurface< DigitalSurfaceContainer > &dsurf, const CellEmbedder &cembedder, PolygonalSurface< typename CellEmbedder::Value > &polysurf, VertexMap &vertexmap)
static void triangulatedSurface2Mesh(const TriangulatedSurface< Point > &trisurf, Mesh< Point > &mesh)
static bool mesh2PolygonalSurface(const Mesh< Point > &mesh, PolygonalSurface< Point > &polysurf)
Aim: This class is defined to represent a surface mesh through a set of vertices and faces....
Definition Mesh.h:92
Size nbFaces() const
void setFaceColor(Index i, const DGtal::Color &aColor)
auto crossProduct(const PointVector< dim, OtherComponent, OtherStorage > &v) const -> decltype(DGtal::crossProduct(*this, v))
Cross product with a PointVector.
static Dimension size()
TEuclideanRing Component
Type for Vector elements.
static Self zero
Static const for zero PointVector.
Aim: Represents a polygon mesh, i.e. a 2-dimensional combinatorial surface whose faces are (topologic...
Aim: A simple point embedder where grid steps are given for each axis. Note that the real point (0,...
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as connected surfels....
Aim: This class is used to simplify shape and surface creation. With it, you can create new shapes an...
Definition Shortcuts.h:102
static Parameters parametersUtilities()
Definition Shortcuts.h:2936
GradientColorMap< Scalar > ColorMap
Definition Shortcuts.h:190
static CountedPtr< BinaryImage > makeBinaryImage(CountedPtr< BinaryImage > bimage, Parameters params=parametersBinaryImage())
Definition Shortcuts.h:625
CellRange PointelRange
Definition Shortcuts.h:172
ImageContainerBySTLVector< Domain, bool > BinaryImage
defines a black and white image with (hyper-)rectangular domain.
Definition Shortcuts.h:138
static bool outputPrimalDigitalSurfaceAsObj(std::ostream &output, CountedPtr< TAnyDigitalSurface > surface, const TCellEmbedder &embedder)
Definition Shortcuts.h:3154
Space::Vector Vector
Vector with integer coordinates.
Definition Shortcuts.h:116
static bool saveOBJ(CountedPtr< ::DGtal::TriangulatedSurface< TPoint > > trisurf, const RealVectors &normals, const Colors &diffuse_colors, std::string objfile, const Color &ambient_color=Color(32, 32, 32), const Color &diffuse_color=Color(200, 200, 255), const Color &specular_color=Color::White)
Definition Shortcuts.h:2831
static CountedPtr< DoubleImage > makeDoubleImage(Domain aDomain)
Definition Shortcuts.h:1191
LightDigitalSurface::ArcRange ArcRange
Definition Shortcuts.h:164
static KSpace getKSpace(CountedPtr< BinaryImage > bimage, Parameters params=parametersKSpace())
Definition Shortcuts.h:351
static std::map< std::string, std::string > getPolynomialList()
Definition Shortcuts.h:233
static Parameters parametersImplicitShape3D()
Definition Shortcuts.h:262
static Parameters parametersKSpace()
Definition Shortcuts.h:308
static CountedPtr< TriangulatedSurface > makeTriangulatedSurface(CountedPtr< ::DGtal::DigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2383
static CountedPtr< DoubleImage > makeDoubleImage(std::string input)
Definition Shortcuts.h:1204
LightDigitalSurface::Surfel Surfel
Definition Shortcuts.h:158
Space::RealPoint RealPoint
Point with floating-point coordinates.
Definition Shortcuts.h:120
static KSpace getKSpace(const Point &low, const Point &up, Parameters params=parametersKSpace())
Definition Shortcuts.h:329
SetOfSurfels< KSpace, SurfelSet > ExplicitSurfaceContainer
defines a heavy container that represents any digital surface.
Definition Shortcuts.h:153
LightDigitalSurface::Vertex Vertex
Definition Shortcuts.h:161
static KSpace getKSpace(Parameters params=parametersKSpace()|parametersDigitizedImplicitShape3D())
Definition Shortcuts.h:483
static bool saveOFF(CountedPtr< ::DGtal::PolygonalSurface< TPoint > > polysurf, std::string off_file, const Color &face_color=DGtal::Color::None)
Definition Shortcuts.h:2739
static CountedPtr< DigitizedImplicitShape3D > makeDigitizedImplicitShape3D(CountedPtr< ImplicitShape3D > shape, Parameters params=parametersDigitizedImplicitShape3D())
Definition Shortcuts.h:520
std::map< Surfel, IdxSurfel > Surfel2Index
Definition Shortcuts.h:185
static bool outputCellMapAsCSV(std::ostream &output, const KSpace &K, const TCellMap &anyMap, const TValueWriter &writer)
Definition Shortcuts.h:3486
static CountedPtr< DigitalSurface > makeDigitalSurface(CountedPtr< IdxDigitalSurface > idx_surface, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1501
static bool outputPrimalIdxDigitalSurfaceAsObj(std::ostream &output, CountedPtr< IdxDigitalSurface > surface)
Definition Shortcuts.h:3172
static CellRange getCellRange(Cell2Index &c2i, CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface, const Dimension k)
Definition Shortcuts.h:1660
static CountedPtr< SurfaceMesh > makeSurfaceMesh(const std::string &path)
Definition Shortcuts.h:2677
Shortcuts(Shortcuts &&other)=delete
static bool saveOBJ(CountedPtr< ::DGtal::SurfaceMesh< TPoint, TVector > > surf, const RealVectors &normals, const Colors &diffuse_colors, std::string objfile, const Color &ambient_color=Color(32, 32, 32), const Color &diffuse_color=Color(200, 200, 255), const Color &specular_color=Color::White)
Definition Shortcuts.h:2874
static SurfelRange getSurfelRange(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface, const Surfel &start_surfel, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1831
RealVector::Component Scalar
Floating-point numbers.
Definition Shortcuts.h:122
::DGtal::TriangulatedSurface< RealPoint > TriangulatedSurface
Definition Shortcuts.h:182
std::map< Cell, IdxVertex > Cell2Index
Definition Shortcuts.h:186
static bool outputDualDigitalSurfaceAsObj(std::ostream &output, CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface, const TCellEmbedder &embedder, const Parameters &params=parametersMesh())
Definition Shortcuts.h:3260
static CountedPtr< PolygonalSurface > makePolygonalSurface(CountedPtr< Mesh > aMesh)
Definition Shortcuts.h:2427
ImageContainerBySTLVector< Domain, float > FloatImage
defines a float image with (hyper-)rectangular domain.
Definition Shortcuts.h:142
static bool saveGrayScaleImage(CountedPtr< GrayScaleImage > gray_scale_image, std::string output)
Definition Shortcuts.h:917
static PointelRange getPointelRange(Cell2Index &c2i, CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:1730
static bool saveOFF(CountedPtr< ::DGtal::TriangulatedSurface< TPoint > > trisurf, std::string off_file, const Color &face_color=DGtal::Color::None)
Definition Shortcuts.h:2911
::DGtal::SurfaceMesh< RealPoint, RealPoint > SurfaceMesh
Definition Shortcuts.h:184
Space::Point Point
Point with integer coordinates.
Definition Shortcuts.h:114
static CellRange getPrimalVertices(const KSpace &K, const Surfel &s, bool ccw)
Definition Shortcuts.h:3535
static CellRange getPrimalCells(const KSpace &K, const SCell &s, const Dimension k)
Definition Shortcuts.h:3507
static KSpace getKSpace(CountedPtr< GrayScaleImage > gimage, Parameters params=parametersKSpace())
Definition Shortcuts.h:375
static CountedPtr< BinaryImage > makeBinaryImage(const C1< C2< C3< T > > > &values, std::optional< Domain > override_domain=std::nullopt)
Definition Shortcuts.h:721
Shortcuts()=delete
std::vector< Color > Colors
Definition Shortcuts.h:189
static Parameters parametersMesh()
Definition Shortcuts.h:2297
static CountedPtr< Mesh > makeMesh(CountedPtr< TriangulatedSurface > triSurf, const Color &aColor=Color::White)
Definition Shortcuts.h:2332
~Shortcuts()=delete
static CountedPtr< FloatImage > makeFloatImage(CountedPtr< ImplicitShape3D > shape, Parameters params=parametersDigitizedImplicitShape3D())
Definition Shortcuts.h:1159
static bool saveOBJ(CountedPtr< ::DGtal::TriangulatedSurface< TPoint > > trisurf, const std::string &objfile)
Definition Shortcuts.h:2765
static std::vector< CountedPtr< LightDigitalSurface > > makeLightDigitalSurfaces(SurfelRange &surfel_reps, CountedPtr< BinaryImage > bimage, const KSpace &K, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1410
static Parameters parametersDigitalSurface()
Definition Shortcuts.h:1257
static CountedPtr< DoubleImage > makeDoubleImage(CountedPtr< ImplicitShape3D > shape, Parameters params=parametersDigitizedImplicitShape3D())
Definition Shortcuts.h:1225
ImplicitPolynomial3Shape< Space > ImplicitShape3D
Definition Shortcuts.h:134
Shortcuts & operator=(const Shortcuts &other)=delete
Space::Integer Integer
Integer numbers.
Definition Shortcuts.h:112
static CountedPtr< FloatImage > makeFloatImage(std::string input)
Definition Shortcuts.h:1138
static KSpace getKSpace(CountedPtr< ::DGtal::IndexedDigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:405
LightDigitalSurface::Face Face
Definition Shortcuts.h:163
::DGtal::Mesh< RealPoint > Mesh
Definition Shortcuts.h:181
static std::vector< CountedPtr< LightDigitalSurface > > makeLightDigitalSurfaces(CountedPtr< BinaryImage > bimage, const KSpace &K, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1380
static CountedPtr< TriangulatedSurface > makeTriangulatedSurface(CountedPtr< PolygonalSurface > polySurf, const Parameters &params=parametersMesh())
Definition Shortcuts.h:2407
static bool outputPrimalDigitalSurfaceAsObj(std::ostream &output, CountedPtr< TAnyDigitalSurface > surface)
Definition Shortcuts.h:3126
static bool saveOFF(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > digsurf, std::string off_file, const Color &face_color=Color(32, 32, 32))
Definition Shortcuts.h:2149
SCellRange SurfelRange
Definition Shortcuts.h:173
LightImplicitDigitalSurface< KSpace, BinaryImage > LightSurfaceContainer
Definition Shortcuts.h:149
static CellRange getPrimalVertices(const KSpace &K, const SCell &s)
Definition Shortcuts.h:3523
static CountedPtr< GrayScaleImage > makeGrayScaleImage(Domain aDomain)
Definition Shortcuts.h:869
MPolynomial< Space::dimension, Scalar > ScalarPolynomial
defines a multi-variate polynomial : RealPoint -> Scalar
Definition Shortcuts.h:131
static CountedPtr< FloatImage > makeFloatImage(Domain aDomain)
Definition Shortcuts.h:1125
static CountedPtr< BinaryImage > makeBinaryImage(const std::vector< T > &positions, std::optional< Domain > override_domain=std::nullopt)
Definition Shortcuts.h:768
static CountedPtr< SurfaceMesh > makePrimalSurfaceMesh(CountedPtr< ::DGtal::IndexedDigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2665
static bool outputPrimalIdxDigitalSurfaceAsObj(std::ostream &output, CountedPtr< IdxDigitalSurface > surface, const TCellEmbedder &embedder)
Definition Shortcuts.h:3195
static SurfelRange getSurfelRange(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1808
KSpace::SurfelSet SurfelSet
defines a set of surfels
Definition Shortcuts.h:146
static CountedPtr< LightDigitalSurface > makeLightDigitalSurface(CountedPtr< BinaryImage > bimage, const KSpace &K, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1323
static CountedPtr< PolygonalSurface > makePrimalPolygonalSurface(CountedPtr< ::DGtal::IndexedDigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2617
static CountedPtr< Mesh > makeMesh(CountedPtr< PolygonalSurface > polySurf, const Color &aColor=Color::White)
Definition Shortcuts.h:2349
static const KSpace & refKSpace(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:416
static CanonicSCellEmbedder< KSpace > getSCellEmbedder(const KSpace &K)
Definition Shortcuts.h:443
static CountedPtr< DigitalSurface > makeDigitalSurface(CountedPtr< TPointPredicate > bimage, const KSpace &K, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1470
std::vector< Cell > CellRange
Definition Shortcuts.h:171
static CountedPtr< BinaryImage > makeBinaryImage(CountedPtr< DigitizedImplicitShape3D > shape_digitization, Parameters params=parametersBinaryImage())
Definition Shortcuts.h:573
static KSpace getKSpace(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:394
static bool outputSurfelsAsObj(std::ostream &output, const SurfelRange &surfels, const TCellEmbedder &embedder)
Definition Shortcuts.h:3075
static CountedPtr< PolygonalSurface > makePrimalPolygonalSurface(Cell2Index &c2i, CountedPtr< ::DGtal::DigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2582
static IdxRange getRangeMatch(const std::vector< TValue > &s1, const std::vector< TValue > &s2, bool perfect=false)
Definition Shortcuts.h:2961
bool isValid() const
Definition Shortcuts.h:3607
ImageContainerBySTLVector< Domain, GrayScale > GrayScaleImage
defines a grey-level image with (hyper-)rectangular domain.
Definition Shortcuts.h:140
static CanonicSCellEmbedder< KSpace > getSCellEmbedder(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:1283
::DGtal::DigitalSurface< ExplicitSurfaceContainer > DigitalSurface
defines an arbitrary digital surface over a binary image.
Definition Shortcuts.h:155
::DGtal::Color Color
Definition Shortcuts.h:188
static CountedPtr< GrayScaleImage > makeGrayScaleImage(const std::vector< T > &values, const Domain &d)
Definition Shortcuts.h:1000
std::vector< IdxVertex > IdxRange
Definition Shortcuts.h:179
IdxDigitalSurface::Vertex IdxSurfel
Definition Shortcuts.h:165
void selfDisplay(std::ostream &out) const
Definition Shortcuts.h:3598
KSpace::Space Space
Digital space.
Definition Shortcuts.h:110
std::vector< RealPoint > RealPoints
Definition Shortcuts.h:177
static CountedPtr< PolygonalSurface > makeDualPolygonalSurface(Surfel2Index &s2i, CountedPtr< ::DGtal::DigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2529
static CountedPtr< PolygonalSurface > makePolygonalSurface(CountedPtr< GrayScaleImage > gray_scale_image, const Parameters &params=parametersKSpace()|parametersBinaryImage()|parametersDigitalSurface())
Definition Shortcuts.h:2449
static bool saveOBJ(CountedPtr< ::DGtal::SurfaceMesh< TPoint, TVector > > surf, const std::string &objfile)
Definition Shortcuts.h:2702
static bool saveOBJ(CountedPtr< ::DGtal::PolygonalSurface< TPoint > > polysurf, const std::string &objfile)
Definition Shortcuts.h:2720
static ZeroTickedColorMap getZeroTickedColorMap(Scalar min, Scalar max, const Parameters &params=parametersUtilities())
Definition Shortcuts.h:3049
IdxDigitalSurface::ArcRange IdxArcRange
Definition Shortcuts.h:168
std::vector< RealVector > RealVectors
Definition Shortcuts.h:176
static bool saveOBJ(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > digsurf, std::string objfile, const Color &ambient_color=Color(32, 32, 32), const Color &diffuse_color=Color(200, 200, 255), const Color &specular_color=Color::White)
Definition Shortcuts.h:2171
std::vector< Scalar > Scalars
Definition Shortcuts.h:175
static CountedPtr< BinaryImage > makeBinaryImage(std::string input, Parameters params=parametersBinaryImage())
Definition Shortcuts.h:653
IndexedDigitalSurface< ExplicitSurfaceContainer > IdxDigitalSurface
defines a connected or not indexed digital surface.
Definition Shortcuts.h:157
std::vector< SCell > SCellRange
Definition Shortcuts.h:170
static CountedPtr< GrayScaleImage > makeGrayScaleImage(std::string input)
Definition Shortcuts.h:882
static CountedPtr< BinaryImage > makeBinaryImage(const std::vector< T > &values, const Domain &d)
Definition Shortcuts.h:691
static CountedPtr< IdxDigitalSurface > makeIdxDigitalSurface(const std::vector< CountedPtr< LightDigitalSurface > > &surfaces, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1625
static bool saveVectorFieldOBJ(const RealPoints &positions, const RealVectors &vf, double thickness, const Colors &diffuse_colors, std::string objfile, const Color &ambient_color=Color(32, 32, 32), const Color &diffuse_color=Color(200, 200, 255), const Color &specular_color=Color::White)
Definition Shortcuts.h:2200
::DGtal::PolygonalSurface< RealPoint > PolygonalSurface
Definition Shortcuts.h:183
static CanonicSCellEmbedder< KSpace > getSCellEmbedder(CountedPtr< ::DGtal::IndexedDigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:1305
Shortcuts(const Shortcuts &other)=delete
BOOST_CONCEPT_ASSERT((concepts::CCellularGridSpaceND< TKSpace >))
static const KSpace & refKSpace(CountedPtr< ::DGtal::IndexedDigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:427
GaussDigitizer< Space, ImplicitShape3D > DigitizedImplicitShape3D
defines the digitization of an implicit shape.
Definition Shortcuts.h:136
static bool saveBinaryImage(CountedPtr< BinaryImage > bimage, std::string output)
Definition Shortcuts.h:841
IdxVertex Idx
Definition Shortcuts.h:178
std::vector< IdxSurfel > IdxSurfelRange
Definition Shortcuts.h:174
static Parameters parametersBinaryImage()
Definition Shortcuts.h:544
static CountedPtr< GrayScaleImage > makeGrayScaleImage(const std::vector< T > &positions, const std::vector< U > &values, std::optional< Domain > override_domain=std::nullopt)
Definition Shortcuts.h:1077
static CountedPtr< GrayScaleImage > makeGrayScaleImage(const C1< C2< C3< T > > > &values, std::optional< Domain > override_domain=std::nullopt)
Definition Shortcuts.h:1029
static CountedPtr< BinaryImage > makeBinaryImage(CountedPtr< GrayScaleImage > gray_scale_image, Parameters params=parametersBinaryImage())
Definition Shortcuts.h:818
IdxDigitalSurface::Arc IdxArc
Definition Shortcuts.h:167
static Parameters defaultParameters()
Definition Shortcuts.h:200
static CountedPtr< IdxDigitalSurface > makeIdxDigitalSurface(CountedPtr< BinaryImage > bimage, const KSpace &K, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1536
static CountedPtr< GrayScaleImage > makeGrayScaleImage(CountedPtr< BinaryImage > binary_image, std::function< GrayScale(bool) > const &bool2grayscale=[](bool v) { return v ?(unsigned char) 255 :(unsigned char) 0;})
Definition Shortcuts.h:896
Space::RealVector RealVector
Vector with floating-point coordinates.
Definition Shortcuts.h:118
static bool saveOBJ(CountedPtr< ::DGtal::PolygonalSurface< TPoint > > polysurf, const RealVectors &normals, const Colors &diffuse_colors, std::string objfile, const Color &ambient_color=Color(32, 32, 32), const Color &diffuse_color=Color(200, 200, 255), const Color &specular_color=Color::White)
Definition Shortcuts.h:2789
static CountedPtr< TriangulatedSurface > makeTriangulatedSurface(CountedPtr< GrayScaleImage > gray_scale_image, const Parameters &params=parametersKSpace()|parametersBinaryImage()|parametersDigitalSurface())
Definition Shortcuts.h:2492
static bool outputDualDigitalSurfaceAsObj(std::ostream &output, CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface, const Parameters &params=parametersMesh())
Definition Shortcuts.h:3226
static Parameters parametersDigitizedImplicitShape3D()
Definition Shortcuts.h:458
LightDigitalSurface::Arc Arc
Definition Shortcuts.h:162
ImageContainerBySTLVector< Domain, double > DoubleImage
defines a double image with (hyper-)rectangular domain.
Definition Shortcuts.h:144
static CountedPtr< GrayScaleImage > makeGrayScaleImage(CountedPtr< FloatImage > fimage, Parameters params=parametersGrayScaleImage())
Definition Shortcuts.h:937
static CountedPtr< IdxDigitalSurface > makeIdxDigitalSurface(const TSurfelRange &surfels, ConstAlias< KSpace > K, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1569
IdxDigitalSurface::Vertex IdxVertex
Definition Shortcuts.h:166
unsigned char GrayScale
The type for 8-bits gray-scale elements.
Definition Shortcuts.h:126
static PointelRange getCellRange(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface, const Dimension k)
Definition Shortcuts.h:1699
static CountedPtr< TriangulatedSurface > makeTriangulatedSurface(Surfel2Index &s2i, CountedPtr< ::DGtal::DigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2365
static CountedPtr< SurfaceMesh > makePrimalSurfaceMesh(CountedPtr< ::DGtal::DigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2651
static CountedPtr< PolygonalSurface > makeDualPolygonalSurface(CountedPtr< ::DGtal::DigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2549
static CountedPtr< SurfaceMesh > makePrimalSurfaceMesh(Cell2Index &c2i, CountedPtr< ::DGtal::DigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2633
static ColorMap getColorMap(Scalar min, Scalar max, const Parameters &params=parametersUtilities())
Definition Shortcuts.h:3011
static PointelRange getPointelRange(const KSpace &K, const SCell &surfel)
Definition Shortcuts.h:1787
std::set< IdxSurfel > IdxSurfelSet
Definition Shortcuts.h:169
HyperRectDomain< Space > Domain
An (hyper-)rectangular domain.
Definition Shortcuts.h:124
static PointelRange getPointelRange(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:1771
static CanonicCellEmbedder< KSpace > getCellEmbedder(CountedPtr< ::DGtal::IndexedDigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:1294
static bool outputSCellMapAsCSV(std::ostream &output, const KSpace &K, const TSCellMap &anyMap, const TValueWriter &writer)
Definition Shortcuts.h:3456
static IdxSurfelRange getIdxSurfelRange(CountedPtr< IdxDigitalSurface > surface, const IdxSurfel &start_surfel, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1893
static bool saveOBJ(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > digsurf, const RealVectors &normals, const Colors &diffuse_colors, std::string objfile, const Color &ambient_color=Color(32, 32, 32), const Color &diffuse_color=Color(200, 200, 255), const Color &specular_color=Color::White)
Definition Shortcuts.h:2120
static std::vector< TValue > getMatchedRange(const std::vector< TValue > &range, const IdxRange &match)
Definition Shortcuts.h:2996
TKSpace KSpace
Digital cellular space.
Definition Shortcuts.h:108
LightDigitalSurface::SCell SCell
Definition Shortcuts.h:160
static IdxSurfelRange getIdxSurfelRange(CountedPtr< IdxDigitalSurface > surface, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1873
static CountedPtr< BinaryImage > makeBinaryImage(CountedPtr< DigitizedImplicitShape3D > shape_digitization, Domain shapeDomain, Parameters params=parametersBinaryImage())
Definition Shortcuts.h:593
static bool saveOBJ(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > digsurf, const TCellEmbedder &embedder, const RealVectors &normals, const Colors &diffuse_colors, std::string objfile, const Color &ambient_color=Color(32, 32, 32), const Color &diffuse_color=Color(200, 200, 255), const Color &specular_color=Color::White)
Definition Shortcuts.h:2000
static bool saveOFF(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > digsurf, const TCellEmbedder &embedder, std::string off_file, const Color &face_color=DGtal::Color::None)
Definition Shortcuts.h:1934
TickedColorMap< Scalar, ColorMap > ZeroTickedColorMap
Definition Shortcuts.h:191
::DGtal::DigitalSurface< LightSurfaceContainer > LightDigitalSurface
defines a connected digital surface over a binary image.
Definition Shortcuts.h:151
static Parameters parametersGrayScaleImage()
Definition Shortcuts.h:856
static CountedPtr< BinaryImage > makeBinaryImage(Domain shapeDomain)
Definition Shortcuts.h:558
static CanonicCellEmbedder< KSpace > getCellEmbedder(const KSpace &K)
Definition Shortcuts.h:435
static CountedPtr< IdxDigitalSurface > makeIdxDigitalSurface(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1602
static CountedPtr< PolygonalSurface > makePrimalPolygonalSurface(CountedPtr< ::DGtal::DigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2602
static CountedPtr< ImplicitShape3D > makeImplicitShape3D(const Parameters &params=parametersImplicitShape3D())
Definition Shortcuts.h:279
static CountedPtr< GrayScaleImage > makeGrayScaleImage(CountedPtr< DoubleImage > fimage, Parameters params=parametersGrayScaleImage())
Definition Shortcuts.h:969
static CanonicCellEmbedder< KSpace > getCellEmbedder(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface)
Definition Shortcuts.h:1272
static CountedPtr< PolygonalSurface > makeDualPolygonalSurface(CountedPtr< ::DGtal::IndexedDigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2564
static CountedPtr< TriangulatedSurface > makeTriangulatedSurface(CountedPtr< Mesh > aMesh)
Definition Shortcuts.h:2315
LightDigitalSurface::Cell Cell
Definition Shortcuts.h:159
TInteger Integer
Arithmetic ring induced by (+,-,*) and Integer numbers.
Definition SpaceND.h:102
static SCell findABel(const KSpace &K, const PointPredicate &pp, unsigned int nbtries=1000)
static void sMakeBoundary(SCellSet &aBoundary, const KSpace &aKSpace, const PointPredicate &pp, const Point &aLowerBound, const Point &aUpperBound)
Aim: This class adapts any colormap to add "ticks" in the colormap colors.
std::ostream & warning()
std::ostream & error()
Aim: Represents a triangulated surface. The topology is stored with a half-edge data structure....
Aim: Define a simple Foreground predicate thresholding image values between two constant values (the ...
CountedPtr< SH3::DigitalSurface > surface
CountedPtr< SH3::BinaryImage > binary_image
BreadthFirstVisitor< MyDigitalSurface > Visitor
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & operator<<(std::ostream &out, const ClosedIntegerHalfPlane< TSpace > &object)
DGtal::uint32_t Dimension
Definition Common.h:119
Trace trace
Aim: A trivial embedder for signed and unsigned cell, which corresponds to the canonic injection of c...
Aim: A trivial embedder for signed cell, which corresponds to the canonic injection of cell centroids...
static TContainer import(const std::string &filename, std::vector< unsigned int > dimSpace=std::vector< unsigned int >())
Aim: Provide a mechanism to save image (2D or 3D) into file with the best saver loader according to a...
static bool export2OFF(std::ostream &out, const Mesh< TPoint > &aMesh, bool exportColor=true)
Cell operator()(std::istream &input, const KSpace &K)
Definition Shortcuts.h:3366
void operator()(std::ostream &output, const KSpace &K, const Cell &cell)
Definition Shortcuts.h:3359
SCell operator()(std::istream &input, const KSpace &K)
Definition Shortcuts.h:3382
void operator()(std::ostream &output, const KSpace &K, const SCell &scell)
Definition Shortcuts.h:3375
bool operator()(std::istream &input, Value &value)
Definition Shortcuts.h:3407
bool operator()(std::istream &input, std::vector< Value > &values)
Definition Shortcuts.h:3422
void operator()(std::ostream &output, const Value &v)
Definition Shortcuts.h:3395
void operator()(std::ostream &output, const std::vector< Value > &vv)
Definition Shortcuts.h:3399
static bool readOBJ(std::istream &input, SurfaceMesh &smesh)
Aim: Represents an embedded mesh as faces and a list of vertices. Vertices may be shared among faces ...
Definition SurfaceMesh.h:92
Aim: A cell embedder is a mapping from unsigned cells to Euclidean points. It adds inner types to fun...
Aim: This concept describes a cellular grid space in nD. In these spaces obtained by cartesian produc...
int max(int a, int b)
KSpace K
HalfEdgeDataStructure::Size Size
MPolynomialReader< 3, Ring > Polynomial3Reader
Domain domain
Image image(domain)
HyperRectDomain< Space > Domain